在代码重新生成之间保留 DisplayName
Preserve DisplayName between code regeneration
我在 SQL 服务器中创建了一个数据库,并在我的 C# MVC 5 项目中使用 Entity Framework 创建了一个模型。在我的模型中,我使用 System.ComponentModel 为多个属性(或列)提供 DisplayName。示例:
namespace ProjectTracking.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
public partial class EmployeeType
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public EmployeeType()
{
this.Employees = new HashSet<Employee>();
}
[DisplayName("Employee Type ID")]
public int PK_EmployeeTypeID { get; set; }
[DisplayName("Employee Type Name")]
public string EmployeeTypeName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Employee> Employees { get; set; }
}
}
我 运行 遇到的问题是,如果我更新数据库并更新我的模型,我会丢失所有这些信息,因为所有模型 类 都会重新生成。有没有办法保存这些信息?
您最好的选择是不直接使用 Entity Framework 实体作为视图模型。相反,创建表示需要显示的内容的视图模型,并将实体的值映射到视图模型(使用 AutoMapper 使这变得轻而易举)。
What do you mean by "directly as View Models"
您的代码可能如下所示:
public class MyContextDb
{
public DbSet<EmployeeType> EmployeeTypes { get; set; }
}
public class MyController
{
public ActionResult Index()
{
using (var db = new MyDbContext)
{
var emp = db.EmployeeTypes.FirstOrDefault();
return View(emp); // <-- passing EF entity as view model
}
}
}
相反
public EmployeeTypeVM
{
// Properties you want to expose and annotate
}
using (var db = new MyDbContext)
{
var emp = db.EmployeeTypes.FirstOrDefault();
var vm = Mapper.Map<EmployeeTypeVM>(emp);
return View(vm); // <-- passing view model
}
我总是推荐这种方法,因为您通常不会更改 emp,只是具有逻辑和意外的 vm SaveChanged()
不会影响实际数据。
EF 正在使用 T4 模板生成代码。你不应该编辑这些文件,因为它们可以在你打开设计器时随时重新生成。
有一种方法可以做到这一点,使用 MetadataTypeAttribute
`
EF 将模型生成为部分 classes,因此您可以在不同的文件中添加另一部分,该部分不会重新生成并向其中添加 MetadataTypeAttribute
。这将指向另一个 class,您可以在其中复制属性并提供 DisplayNameAttribute
。像这样:
[MetadataType(typeof(EmployeeTypeMetaData))]
public partial class EmployeeType { }
public class EmployeeTypeMetaData
{
[Required(ErrorMessage = "Title is required.")]
public object Title;
// etc
}
这将是工作...但是:
您不应使用它,原因如下:
- 这会给您带来维护方面的噩梦。每当您的模型发生变化时,您也需要更改元数据
- 切勿在某种视图中直接使用 ef 模型。使用 DTO objects in between and map between the ef models and the DTO. Mapping can be done either by hand of by a tool like AutoMapper
我在 SQL 服务器中创建了一个数据库,并在我的 C# MVC 5 项目中使用 Entity Framework 创建了一个模型。在我的模型中,我使用 System.ComponentModel 为多个属性(或列)提供 DisplayName。示例:
namespace ProjectTracking.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
public partial class EmployeeType
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public EmployeeType()
{
this.Employees = new HashSet<Employee>();
}
[DisplayName("Employee Type ID")]
public int PK_EmployeeTypeID { get; set; }
[DisplayName("Employee Type Name")]
public string EmployeeTypeName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Employee> Employees { get; set; }
}
}
我 运行 遇到的问题是,如果我更新数据库并更新我的模型,我会丢失所有这些信息,因为所有模型 类 都会重新生成。有没有办法保存这些信息?
您最好的选择是不直接使用 Entity Framework 实体作为视图模型。相反,创建表示需要显示的内容的视图模型,并将实体的值映射到视图模型(使用 AutoMapper 使这变得轻而易举)。
What do you mean by "directly as View Models"
您的代码可能如下所示:
public class MyContextDb
{
public DbSet<EmployeeType> EmployeeTypes { get; set; }
}
public class MyController
{
public ActionResult Index()
{
using (var db = new MyDbContext)
{
var emp = db.EmployeeTypes.FirstOrDefault();
return View(emp); // <-- passing EF entity as view model
}
}
}
相反
public EmployeeTypeVM
{
// Properties you want to expose and annotate
}
using (var db = new MyDbContext)
{
var emp = db.EmployeeTypes.FirstOrDefault();
var vm = Mapper.Map<EmployeeTypeVM>(emp);
return View(vm); // <-- passing view model
}
我总是推荐这种方法,因为您通常不会更改 emp,只是具有逻辑和意外的 vm SaveChanged()
不会影响实际数据。
EF 正在使用 T4 模板生成代码。你不应该编辑这些文件,因为它们可以在你打开设计器时随时重新生成。
有一种方法可以做到这一点,使用 MetadataTypeAttribute
`
EF 将模型生成为部分 classes,因此您可以在不同的文件中添加另一部分,该部分不会重新生成并向其中添加 MetadataTypeAttribute
。这将指向另一个 class,您可以在其中复制属性并提供 DisplayNameAttribute
。像这样:
[MetadataType(typeof(EmployeeTypeMetaData))]
public partial class EmployeeType { }
public class EmployeeTypeMetaData
{
[Required(ErrorMessage = "Title is required.")]
public object Title;
// etc
}
这将是工作...但是:
您不应使用它,原因如下:
- 这会给您带来维护方面的噩梦。每当您的模型发生变化时,您也需要更改元数据
- 切勿在某种视图中直接使用 ef 模型。使用 DTO objects in between and map between the ef models and the DTO. Mapping can be done either by hand of by a tool like AutoMapper