5

为了使用实体框架实现域驱动设计,我使用了 Julie Lerman 在 TechEd North America 2013 上提出的方法(http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DEV-B336#fbid=4tnuPF6L-Jc)。此方法使用 EF 实体类作为域类。对于不同的有界上下文,域实体类具有不同的属性,甚至可能有不同的名称,尽管它们将数据存储在同一个表中。示例是“客户服务”有界上下文中的客户实际上是“客户”,但在“运输”有界上下文中,他是仅具有客户属性子集的“收件人”。对于每个有界上下文,存在一个不同的 EF 上下文,其中仅包含有界上下文所需实体的 DbSet。通过重写 OnModelCreating,我们甚至可以排除与有界上下文无关的引用实体。这部分使用 POCO 很容易实现。

问题是使用 Code First 时的数据库创建。如果我们让 Code First 为每个不同的 EF 上下文创建数据库,我们最终会得到多个数据库。如果我们在 EF 上下文的构造函数中定义数据库名称,则使用第一个使用的 EF 上下文创建数据库,并且在使用第二个 EF 上下文(缺少实体、缺少属性等)时,我们会收到 InvalidOperationException(表示模型已更改)。如果使用的 EF 上下文使用之前没有的其他 EF 上下文的实体/成员,我们可能可以使用迁移来更新数据库。但这肯定会与迁移的正常使用混淆,并且无法正常工作。作为临时解决方案,我仅将单独的 EF 上下文用于数据库创建。这意味着我必须为此再次实现所有 EF 实体。

我确信还有其他解决方案。所以,请(朱莉)告诉我们怎么做。

4

2 回答 2

2

本质上,我相信您将必须拥有一个主上下文,该上下文定义了所有“表”并驱动迁移。此上下文用于创建数据库。

所有后续的“有界”上下文都将在其构造函数中包含 Database.SetInitializer(null) 以防止它们篡改数据库模式。

此外,您的主上下文和“有界”上下文都应该从具有连接字符串和此类集合的抽象基上下文类继承。

当您的应用程序启动时,您可以简单地尝试实例化您的主上下文并确保它已迁移到最新版本。但是在您以后的实际应用程序中,您只使用仅实现主上下文的子集的“有界”上下文。

我意识到你已经部分或全部地做这件事,但我认为这是要走的路。

于 2014-02-08T12:22:26.230 回答
1

我同意 Julie Lermans 的建议。Indded 一段时间以来,她一直在建议这种方法。而且您不需要 EF6 来执行此操作。尽管使用 EF6 可以更轻松地进行管理。

声明尽可能多的上下文。关键是在上下文创建过程中数据库的初始化设置。基本模式如下

例如

// when you wish to migrate
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YOURCONTEXT, YourContentConfiguration>());
var connie = new YOURCONTEXT(.....);

//When you wish to access but NOT change the DB with a small context.
Database.SetInitializer(new ContextInitializerNone<BoundedMiniDbContext>());
var connie = new BoundedMiniDbContext(.....);

其中 yourContent 继承自 DbContext 并且 YourContextConfig 继承 DbMigrationsConfiguration

于 2013-11-09T03:08:55.247 回答