类是由Entity Framework数据库类还是业务类生成的?

时间:2017-08-04 08:54:03

标签: c# entity-framework domain-driven-design

我有一个三层应用程序,其中一个类库作为基础结构层,它包含一个实体框架数据模型(数据库优先)。

Entity Framework在Model.tt文件夹下创建实体。这些类填充了数据库中的数据。

过去我会将Entity Framework创建的类(在数据项目中)映射到Domain项目中的类,例如Infrastructure.dbApplication已映射到Domain.Application。

我的阅读告诉我,我应该使用.tt中包含的类作为域类,即将域方法添加到Entity Framework生成的类中。但是,这意味着域类将包含在基础结构项目中,不是吗?是否可以将Entity框架生成的类重定位到Domain项目?我在这里遗漏了一些基本的东西吗?

3 个答案:

答案 0 :(得分:0)

您可以通过在域项目中创建新项目来重定位实体类:DbContext EF 6.x Generator(不确定名称,您可能必须安装插件才能在列表中获取此项目,EF也存在5.x的)。

创建此新项目后,您必须对其进行编辑,以便在文件的最开头设置EDMX的路径。例如,在我的项目中,它是:

const string inputFile = @"..\..\DAL.Impl\GlobalSales\Mapping\GlobalSalesContext.edmx";

您还需要编辑DbContext.tt文件,以便在生成的类顶部添加权限。在您在EDMX上完成的每次更改时,您还必须右键单击生成器并单击:"运行自定义工具"生成新类。

话虽如此,这是一个好习惯吗?正如您所看到的那样,我在项目中所做的一切。只要您在生成的实体类中没有EF特定注释或类似的东西,我就会说它是可以接受的。

如果你需要更改你的ORM,你可以保留生成的类并删除所有EF的东西(.tt文件等),你的应用程序的其余部分将工作相同。但这是基于意见的。

答案 1 :(得分:0)

您应该将模型移动到其他项目。这是一种很好的做法。我并没有完全明白你的意思"转到Domain project"通常,实体框架生成的类用作域模型。无需创建"不同的"域模型由此而来。此模型应仅用于数据库操作附近,而Web(窗口)应用程序应仅使用DTO(域转移对象)

我不知道你是否使用它 - 但这是一个很好的工具,允许从数据库中重建模型:

https://marketplace.visualstudio.com/items?itemName=SimonHughes.EntityFrameworkReversePOCOGenerator

这允许在类中存储模型(而不是EDMX)有人将其称为"代码优先"但是有一个误解。人们可以使用这个工具来创建模型,并且仍然可以在数据库中使用#34;这样做只是为了省略使用EDMX作为模型定义。

答案 2 :(得分:0)

我认为在真正意义上它是数据模型 - 而不是域模型。虽然人们谈论将实体框架模型作为域概念,但我不知道如何轻松地改造适合的Value对象,例如说明在真正的域意义上表示的数量:

public class CustomerTransaction
{
    public int Id { get; set; }
    public string TransactionNumber { get; set; }
    public Amount Amount { get; set; }
}

public class Amount
{
     public decimal Value { get; }
     public Currency Currency { get; }
}

与更不正确的数据模型方法相反:

public class CustomerTransaction
{
    public int Id { get; set; }
    public string TransactionNumber { get; set; }
    public int CurrencyType { get; set; }
    public decimal Amount { get; set; }
}

是的,这个例子很贫乏,但为了清楚起见只对属性感兴趣 - 而不是行为。无论是否需要“业务/数据对象”的默认构造函数,您都需要更改属性的可见性。

因此,在域意义上,Amount是客户交易中的价值对象 - 我假设它是示例中的一个实体。

那么这将如何通过Entity Framework转换为数据库映射。在单个CustomerTransaction表中可能会将上述内容保留为数据模型中的平面结构,但我的方法是在其周围添加一个额外的存储库并映射到数据结构。

Udi Dahan在真正意义上有一些关于DDD和ORM的好信息。我在某处谈到DDD和ORM将数据模型实例作为域对象中的私有字段,但我可能错了。

此外,该数据模型遭受了原始痴迷(我认为Fowler在他的重构书中创造了它 - 虽然它在他的书中)Jimmy Bogard talks about that here

查看Udi Dahan内容。