实体框架的自动生成的类的代码会在每次更新模型时生成
问题描述:
我正在使用连接到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; }
}
答
您正在使用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; }
结论:
- 仅限使用
MetadataType
用于将DataAnnotation Attribtues添加到生成的属性中。 - 不要创建已经在分部类中生成的变量。如果你想给它一个属性,参见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
。
切勿触摸生成的代码,因为它的性质将被生成并将覆盖您所做的任何更改。 –
该代码由** T4模板**生成,您可以*根据自己的需要适应您的需要,如果您愿意的话。所以是的,如果你想这样做,你可以修改/修改你的EF T4模板* not *来生成基本实体类的任何属性,因为你在元数据类中指定了所有的东西。用于“EF T4代码生成”的Google(或Bing) - 加载命中 –
您可以先下载此NuGet包:'EntityFramework.CodeTemplates.CSharp',然后查看安装到'CodeTemplates'文件夹中的两个T4模板。当您运行“先从现有数据库生成代码”代时使用这些代码。其他T4模板存在其他场景 –