在代码重新生成之间保留DisplayName

时间:2017-11-08 21:16:08

标签: c# asp.net-mvc entity-framework model data-annotations

我在SQL Server中创建了一个数据库,并使用Entity Framework在我的C#MVC 5项目中创建了一个模型。在我的模型中,我使用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; }
    }
}

我遇到的问题是,如果我更新数据库并更新我的模型,我会丢失所有这些信息,因为所有的模型类都被重新生成。有没有办法坚持这些信息?

2 个答案:

答案 0 :(得分:2)

EF正在使用T4模板生成代码。您永远不应该编辑这些文件,因为它们可以在您打开设计器时随时重新生成。

使用MetadataTypeAttribute`

可以做到这一点

EF将模型生成为部分类,因此您可以在另一个文件中添加另一个部分,该部分不会被重新生成,而MetadataTypeAttribute也会重新生成。DisplayNameAttribute。这将指向另一个类,您可以在其中复制属性并提供[MetadataType(typeof(EmployeeTypeMetaData))] public partial class EmployeeType { } public class EmployeeTypeMetaData { [Required(ErrorMessage = "Title is required.")] public object Title; // etc } 。像这样:

{{1}}

这就是工作......但是:

您不应该出于以下原因使用它:

  • 这会给你一个维护噩梦。每当您的模型发生变化时,您还需要更改元数据
  • 您不应该在某种视图中直接使用您的ef模型。在两者之间使用DTO个对象,并在ef模型和DTO之间进行映射。映射可以通过AutoMapper
  • 等工具手动完成

答案 1 :(得分:1)

您最好的选择是不要将Entity Framework实体直接用作View Models。而是创建表示需要显示的内容的视图模型,并将实体中的值映射到视图模型上(使用AutoMapper使这成为一个蛋糕行走)。

  

“直接作为视图模型”是什么意思

您的代码可能如下所示:

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()不会影响实际数据。