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

3

14

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>
Radmilla answered 25/3, 2013 at 18:58 Comment(2)
Try adding MetadataType - and making a partial class with attributes - if that's the issue you're facing - take a look at these links - let me know how it works - #14412968 - #5889849Sigler
I guess you can try POCO generatorReno
D
14

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.

Derosier answered 25/3, 2013 at 20:41 Comment(1)
Good answer - and spot-on subsequent gotcha!Willywilly
H
5

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; }
    }
}
Husky answered 20/6, 2014 at 14:45 Comment(0)
Y
2

Note that the generated class is a partial Class. So you can create another partial class with same name and do the annotation on that. Then the second partial class will not refresh if you change .edmx file.

More on MVC DB first Fix display Name

Yellowgreen answered 1/8, 2013 at 5:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.