【问题标题】:Business-logic type methods in Entity Framework Code First approach classesEntity Framework Code First 方法类中的业务逻辑类型方法
【发布时间】:2014-02-14 13:12:10
【问题描述】:

我想知道是否可以在与实体框架代码优先方法一起使用的模型类上添加特定于域的方法。

例如下面的dummy方法:

public class Student
{
    public Student()
    { 

    }

    public int StudentID { get; set; }
    public string StudentName { get; set; }

    // Dummy method
    public string StudentNamePlusALetter(string letter)
    {
        return (this.StudentName + letter)
    }
}

如果不可能,我应该在哪里添加它们?

提前谢谢你。

【问题讨论】:

  • 是的,您可以这样做。代码优先就是简单的类。
  • 你可以这样做,但我担心关注点分离。此外,您将无法在针对上下文的任何查询中使用该属性,因为 SQL 中不存在该操作。
  • 您还有什么建议?
  • 您可以通过提供模型类(它们只是直接映射到存储在数据库中的实体(行)的容器)和对模型类进行操作的模型“服务”来分离关注点,从而扩展了上游调用者希望他们提供。在上面的示例中,您可能有一个 StudentNameFormatter 类,它公开了一个 StudentNamePlusALetter() 方法(将 Studentstring 传递给它)。
  • 我应该扩展模型类还是新建一个?

标签: c# asp.net entity-framework ef-code-first


【解决方案1】:

当然可以,但需要注意的是 StudentNamePlusALetter() 的值不会存储在您的数据库中(因为只有属性会被序列化)。

【讨论】:

  • 这对于原始问题中的 Method() 是正确的,但是如果您添加一个具有“setter”的额外属性,那么这里还有更多内容。请参阅下面的示例。
【解决方案2】:

我通常通过 2 个“部分”课程来做到这一点。一种用于直接映射的数据库属性。一个用于额外的东西。

在一个名为 Employee.cs 的文件中

public partial class Employee
{
    public Employee()
    {

    }

    public System.Guid EmployeeUUID { get; set; }

    public string SSN { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public System.DateTime ? CreateDate { get; set; }
    public System.DateTime HireDate { get; set; }

}

然后在一个名为 EmployeeExtended.cs 的文件中

public partial class Employee
{
    public string EmployeeFullName
    {
        get
        {
            return string.Format("{0}, {1} ('{2}')", this.LastName, this.FirstName, this.SSN);
        }
    }


}

请注意,我有一个只读(“get”)属性(“EmployeeFullName”),它可以在 EF 中正常工作,无需更改。

我也可以这样做:

public partial class Employee
{
    public string EmployeeFullName
    {
        get
        {
            return string.Format("{0}, {1} ('{2}')", this.LastName, this.FirstName, this.SSN);
        }
    }

    public string SomeNonTrackedDatabaseProperty { get; set; }

}

但是我必须在“SomeNonTrackedDatabaseProperty”的映射中添加一个“.Ignore”,因为它不是数据库中的列..

 public class EmployeeMap : EntityTypeConfiguration<Employee>
    {
        public EmployeeMap()
        {
            // Primary Key
            this.HasKey(t => t.EmployeeUUID);


            this.Property(t => t.SSN)
                .IsRequired()
                .HasMaxLength(11);

            this.Property(t => t.LastName)
                .IsRequired()
                .HasMaxLength(64);

            this.Property(t => t.FirstName)
                .IsRequired()
                .HasMaxLength(64);

            // Table & Column Mappings
            this.ToTable("Employee");
            this.Property(t => t.EmployeeUUID).HasColumnName("EmployeeUUID");

            this.Property(t => t.SSN).HasColumnName("SSN");
            this.Property(t => t.LastName).HasColumnName("LastName");
            this.Property(t => t.FirstName).HasColumnName("FirstName");
            this.Property(t => t.CreateDate).HasColumnName("CreateDate");
            this.Property(t => t.HireDate).HasColumnName("HireDate");



            this.Ignore(t => t.SomeNonTrackedDatabaseProperty);


        }
    }
}

【讨论】:

  • 如果你想最小化你的配置代码,你也可以在 EmployeeExtended.cs 中使用 [NotMapped] 属性来装饰属性。
  • @txavier “如果你想最小化你的配置代码”或者“~不分离 poco 和 orm 映射的关注点”哈哈!这就是为什么他们给你选择......有些人更喜欢一种方式而不是另一种方式。我是“关注点分离”的窥视者!感谢您对替代方法的评论。
【解决方案3】:

扩展方法在这里也不错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 2016-02-14
    • 2013-01-30
    • 2017-05-31
    相关资源
    最近更新 更多