实体框架的自动生成的类的代码会在每次更新模型时生成

问题描述:

我正在使用连接到SQL Server数据库以生成实体类的ADO.Net实体数据模型。实体框架的自动生成的类的代码会在每次更新模型时生成

我创建生成的类部分类与此属性:

[MetadataType(typeof(Employee))] 

DataAnnotations上的字段。因此,我从生成的类(.g.cs)中移除所有字段,并将它们移动到另一个分类并将数据注释放入此类。

问题是每当我从数据库更新模型时(无论我是从实体数据模型中删除现有表还是只刷新模型,生成的类代码都会被重新生成,而且我必须再次手动删除字段属性从g.cs类,因为它们已经存在于其他分部类(由MetadataType属性指定的类)。

是否有可能,当我更新模型生成的代码没有得到再生,如果需要的话我可以手动再生特定表/类的代码?

[MetadataType(typeof(Employee))] 
    public partial class Employee 
    { 
     public string badge_no { get; set; } 
     public string first_name { get; set; } 
     public string last_name { get; set; } 

     [Display(Name="Name")] 
     public string FullName { get { return first_name + " " + last_name; } } 

     [Display(Name = "Badge-Name")] 
     public string NameAndBadge { get { return badge_no + " " + FullName; } } 
    } 

这里是g.cs文件(生成的文件)

public partial class Employee 
    { 
     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
     public Employee() 
     { 
      this.EmpWrkDesignations = new HashSet<EmpWrkDesignation>(); 
     } 

     public int id { get; set; } 
     //public string badge_no { get; set; } 
     //public string first_name { get; set; } 
     //public string last_name { get; set; } 
     public System.DateTime row_added_date { get; set; } 
     public Nullable<System.DateTime> row_changed_date { get; set; } 

     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
     public virtual ICollection<EmpWrkDesignation> EmpWrkDesignations { get; set; } 
    } 
+0

切勿触摸生成的代码,因为它的性质将被生成并将覆盖您所做的任何更改。 –

+0

该代码由** T4模板**生成,您可以*根据自己的需要适应您的需要,如果您愿意的话。所以是的,如果你想这样做,你可以修改/修改你的EF T4模板* not *来生成基本实体类的任何属性,因为你在元数据类中指定了所有的东西。用于“EF T4代码生成”的Google(或Bing) - 加载命中 –

+0

您可以先下载此NuGet包:'EntityFramework.CodeTemplates.CSharp',然后查看安装到'CodeTemplates'文件夹中的两个T4模板。当您运行“先从现有数据库生成代码”代时使用这些代码。其他T4模板存在其他场景 –

您正在使用MetadataTypeAttribute错误。您应该为注释创建一个单独的类。

我有一个私人的内部类做到这一点,例如:

[MetadataType(typeof(Table1MetaData))] 
public partial class Table1 
{ 
    private class Table1MetaData 
    { 
     [MaxLength(20)] 
     public string Foo { get; set; } 
    } 
} 

重要的是,该元数据类的属性名相同的部分之一。所以上面,是一样的:

public partial class Table1 
{ 
    [MaxLength(20)] 
    public string Foo { get; set; } 
} 

你应该去的第一个。

此外,由于类是不是局部的,:

public string first_name { get; set; } 
public string last_name { get; set; } 

[Display(Name="Name")] 
public string FullName { get { return first_name + " " + last_name; } 

你可以和应该只写你的财产:

[Display(Name="Name")] 
public string FullName { get { return first_name + " " + last_name; } 

结论:

  1. 仅限使用MetadataType用于将DataAnnotation Attribtues添加到生成的属性中。
  2. 不要创建已经在分部类中生成的变量。如果你想给它一个属性,参见1.

这就是说,如果你不舒服Entity Framework生成代码的方式,你可以编辑T4模板。它隐藏在edmx文件后面(只需展开它)。


你没问过,但你会跨越提前或推后传来:

一个陷阱,如果你有自定义属性,并希望得到他们,你需要检查元数据太:

public static TAttribute GetAttributeOrUseMetadata<TAttribute>(this PropertyInfo element, bool inherit = false) where TAttribute : System.Attribute 
{ 
    //Find normal attribute 
    var attribute = element.GetCustomAttribute<TAttribute>(inherit); 
    if (attribute != null) 
    { 
     return attribute; 
    } 

    //Find via MetadataTypeAttribute 
    if (element.DeclaringType != null) 
    { 
     var metadataType = element.DeclaringType.GetCustomAttribute<MetadataTypeAttribute>(inherit); 
     var metadataPropertyInfo = metadataType?.MetadataClassType.GetProperty(element.Name); 
     return metadataPropertyInfo?.GetCustomAttribute<TAttribute>(); 
    } 
    return null; 
} 

MVC替代的,这将是自定义DataAnnotationsModelMetadataProvider