C# 我应该为域和EF使用单独的模型吗?

C# 我应该为域和EF使用单独的模型吗?,c#,entity-framework,C#,Entity Framework,场景:我正在编写一个处理报告生成的程序 我将报告存储在数据库中,映射到EF模型。存在一些非数据库字段(即,一些字段根据数据库中的其他字段自动计算)。让一个类单独映射到DB,另一个类获取该信息并另外具有其他计算字段,这有意义吗 i、 e.与codefirst数据库交互的示例类如下 public class Report{ public int CategoryOneSeverity {get; set;} public int CategoryTwoSeverity {get;se

场景:我正在编写一个处理报告生成的程序

我将报告存储在数据库中,映射到EF模型。存在一些非数据库字段(即,一些字段根据数据库中的其他字段自动计算)。让一个类单独映射到DB,另一个类获取该信息并另外具有其他计算字段,这有意义吗

i、 e.与codefirst数据库交互的示例类如下

public class Report{
    public int CategoryOneSeverity {get; set;}
    public int CategoryTwoSeverity {get;set;}
    public string Title {get;set;}
}
制作另一个类是否有意义,例如:

public class ReportModel{
    public int CategoryOneSeverity;
    public int CategoryTwoSeverity;
    public string Title;

    public int RiskRating{
        get{ return CategoryOneSeverity + CategoryTwoSeverity; }
    }
}    
或者风险评级属性应该在EF模型中

“让一个类单独映射到DB有意义吗 另一个类接受该信息并另外具有 其他计算字段?”

很可能是的。通常,如果我的实体类是HumanResourcesReport,我会创建一个后缀为“ViewModel”的新类,比如HumanResourcesReportViewModel


关于如何使用ViewModels有很多不同的方法,我们可以就术语展开学究式的辩论,但从概念上讲,使用您的实体创建一个新类,其中包含该数据以及处理报告所需的任何附加信息。在本例中,报告生成在某种程度上是MVC模型的视图,因此我认为将保存数据的类称为ViewModel并不令人反感。

您是先使用代码还是先使用数据库

模型中可以有自动计算的字段,但这些字段不会映射到数据库中的字段

这还取决于您的体系结构。如果您首先使用DB,刷新EF模型将更新EF类,从而丢失映射字段。在DB-First场景中,另一种方法是使用EF模型类作为基类,并为报表类继承它

public class ReportModel
{
    public int CategoryOneSeverity;
    public int CategoryTwoSeverity;
    public string Title;
}   

public class ReportClass : ReportModel
{
    public int RiskRating
    { 
        get { return CategoryOneSeverity + CategoryTwoSeverity; }
    }
}

是的,我绝对相信你应该有不同的类来建模你的域,而不是数据库。除非您的应用程序非常琐碎,否则如果您试图直接映射域对象,您总是必须更改它们以匹配您需要的数据结构,并可能公开您不想公开的内容。认为这违反了单一责任原则;如果将类设置为域对象并直接映射它,则类有两个更改的原因。一个是响应不断变化的业务需求,另一个是响应不断变化的数据存储模式。

我想你说的是体系结构的另一端;i、 e.用户界面。在UI中使用ViewModels;这就是为什么它们被称为
View
models.@Robert报表生成在视图的末尾。从数据库中获取数据,将其塑造成ViewModel,然后生成一个报告,作为数据的表示形式。无论它是通过报表引擎还是html引擎生成的,它都是一个视图。你可以随意称呼它,但概念上是一样的。你需要一些不属于实体的额外数据。啊,我明白你的意思。计算RiskRating是一个显示函数。除了最琐碎的应用程序外,这在所有应用程序中都非常糟糕。+1您还可以直接向ReportModel类添加属性,并使用
[NotMapped]
属性标记它们。为您节省一个额外的类,但另一方面,它会使实体类与您可能不经常使用的属性混杂在一起。安迪:没有太多的信息可供选择,只是为了说明通过提供的信息可以实现什么,而不是一个完全可行的解决方案。@KarlGjertsen理解,但我认为最有可能的假设是,应用程序将是不平凡的,基于这一假设,我们应该提供最佳答案。“如果您将类作为域对象并直接映射,则类有两个原因需要更改。一个原因是为了响应不断变化的业务需求,另一个原因是为了响应不断变化的数据存储模式。”-这帮助我将其完美地可视化。谢谢我同意公认的答案,即您应该有单独的类-一个用于建模数据存储,另一个用于建模您的业务领域。然而,您的第二个类违反了许多好的设计原则,其中最明显的是字段不应该公开。我真的不喜欢加入私有成员,然后使用属性来获取它。一个领域不是更有意义吗,尤其是对于预期会发生变化的领域?i、 用户可以随时更改标题。不,事实上,这是没有意义的,正如我所说,这与良好的设计背道而驰。该属性允许您添加验证逻辑,通过转换更改支持字段表示,并最终允许您保持稳定的使用者表面积。让我们的好朋友Jon Skeet说得更好: