How to change [DisplayName] of EF generated class properties?

asp.net-mvc asp.net-mvc-4 ef-database-first entity-framework

Question

We know EF generates classes based on Tables we added to .edmx file. Which will not any [DisplayName] DataAnnotations for them.

How can I add this [DisplayName] of generated classes without modifying them? because generated classes can be overridden If I modify .edmx file (re add the modified table) if database changes. So I don't want modify generate class itself.

EF Generated Class

 public partial class Committee
    {
        public string Committee_Description { get; set; }
        public byte[] Committee_Id { get; set; }
        public string Rn_Descriptor { get; set; }
        public Nullable<System.DateTime> Rn_Create_Date { get; set; }
       ......
       .....

View

 <tr>
            <th>
                @Html.DisplayNameFor(model => model.Item2.GetEnumerator().Current.Committee_Name)
            </th>
1
12
3/25/2013 8:14:53 PM

Accepted Answer

Use a metadata class and attach it to your entity class via the MetadataTypeAttribute. You specify your data annotation attributes on the properties in the metadata class (no implementation for said properties).

MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.metadatatypeattribute.aspx

Edit: an initial gotcha is the namespace of the partial class you define to attach the MetadataTypeAttribute. Be sure to change its namespace to the namespace used by the original entity so that it is defining the same class.

14
3/25/2013 8:41:52 PM

Popular Answer

You can change template .tt file, wich generates classes code to use Documentation property of your model for generating classes with nessesary attributes. For example for EF5 you can replace in *Model.tt method CodeStringGenerator.Property() by:

public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{5} {0} {1} {2} {{ {3}get; {4}set; }}",
        Accessibility.ForProperty(edmProperty),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)),
        (edmProperty.Documentation == null ? "" : ("[Display(Name=\""+edmProperty.Documentation.Summary+"\")]"+Environment.NewLine+"   ")));
}

And CodeStringGenerator.UsingDirectives() with:

public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
    return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
        ? string.Format(
            CultureInfo.InvariantCulture,
            "{0}using System;{1}" +
            "{2}{3}",
            inHeader ? Environment.NewLine : "",
            includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
            inHeader ? "" : Environment.NewLine,"using System.ComponentModel.DataAnnotations;"+Environment.NewLine)
        : "";
}

After that set Documentation.Summary property in model and template .tt will generate all classes with proper attributes without using metadata class and attaching it to your entity class via the MetadataTypeAttribute. For example:

namespace DataAdmin.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public partial class Discount
    {
        public Discount()
        {
            this.DiscountPeriods = new HashSet<DiscountPeriod>();
            this.Clinics = new HashSet<Clinic>();
            this.Doctors = new HashSet<Doctor>();
            this.Servs = new HashSet<Serv>();
        }

        public int DiscountKey { get; set; }
        [Display(Name="Discount name")]
        public string Name { get; set; }
        public string MisCode { get; set; }
        public string MisName { get; set; }
        public string MisDesc { get; set; }
        public decimal Perc { get; set; }
        public int Rang { get; set; }
        public Nullable<int> DiscountTypeKey { get; set; }

        public virtual ICollection<DiscountPeriod> DiscountPeriods { get; set; }
        public virtual ICollection<Clinic> Clinics { get; set; }
        public virtual ICollection<Doctor> Doctors { get; set; }
        public virtual ICollection<Serv> Servs { get; set; }
        public virtual DiscountType DiscountType { get; set; }
    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow