Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>
like image 246
James123 Avatar asked Mar 25 '13 18:03

James123


Video Answer


2 Answers

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.

like image 57
Moho Avatar answered Oct 12 '22 06:10

Moho


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; }
    }
}
like image 23
user3760491 Avatar answered Oct 12 '22 05:10

user3760491