2012-10-25 59 views
5

我刚刚观看了Julie Lermans关于在EF中使用有界上下文的视频(http://www.pluralsight.com/training/Courses/TableOfContents/efarchitecture),现在我正试图找出最佳实施方式(使用POCO)。我看到的两个选择是要么有一个定义所有内容的edmx模型,然后手动创建DbContext来包含适当的实体,或者为每个上下文创建单独的edmx模型并使用自动创建的DbContext。实体框架体系结构中的有界(Db)上下文

有没有人有任何想法,哪一个是最好的或任何优点/缺点?

恕我直言: 对于单个模型来说,它少了很多类并且有更多的代码重用(尽管这些类是自动创建的,所以它只会是手动复制的额外功能),但是我将在一个地方有很多课程,对于需要专业化的课程,每个课程都必须有不同的名称。例如。 Customer,CustomerForFunctionalityX,CustomerForFunctionalityB。

对于不同的模型,我可以对上下文的内容更加严格,因为删除属性并不需要是一个全新的实体,我可以根据需要命名一切(即所有模型都可以使用客户对象即使在模型之间有所不同),但是现在每个上下文都具有完全不同的实体,即使它们全都映射到同一个表 - 这也可能使它们在上下文之间传递它们变得更加困难(但是这不应该需要否则就意味着上下文被定义为错误)。

+0

为什么不使用工作单元模式创建仅显示给定团队将使用的实体的工作单元?如果所有团队都在使用同一个数据库,那么实际上应该只有一个管理数据库的核心团队。有限的上下文似乎与代码一起解决了一个问题,最好的解决方法是团队结构,IMO。 – Maess

+0

当然,添加UOW模式可能会有所帮助,我喜欢UOW模式,尽管它可能会增加复杂性。我喜欢单独的edmxs的主要原因是一个大的edmx可能会变得无法管理,并且还会创建有界的edmxs,以确保数据库开发人员可以确切地看到哪些实体属于某个上下文,而不必为一个UOW在一个中创建定制实体模型 - 在包括数据库模型在内的整个模型中进行分离是很好的。 – user1671016

回答

0

我建议你阅读一下有限上下文是什么以及他们试图解决什么问题。来自有界的上下文definition

明确定义模型适用的上下文。根据团队组织,应用程序特定部分的使用情况以及代码库和数据库模式等物理表现明确设置边界。保持模型在这些范围内严格一致,但不要被分散或混乱的问题以外。

拥有单个EDMX模型会违反该显式边界。你可以想象当不同背景下的团队在同一个EDMX模型上工作时可能发生的摩擦。 但是,对于您的情况,您可能会觉得显式边界和上下文之间的集成成本太高。使用Shared Kernel将允许您在上下文之间共享您的EDMX模型。

+0

朱莉在她的视频中似乎使用了一个edmx,但那只是不和我坐在一起。我同意单个edmx可能会导致摩擦(也是一个巨大的模型!),但是由于只有一个数据库,我不认为在这种情况下我们可以完全符合所有规则。我是否仍然试图遵循这种模式,即使我无法成功地完成它的所有部分? – user1671016

0

,但现在每个上下文具有完全不同的实体,即使他们 都只是映射到同一个表

这是你实际上可能不需要多个限界上下文(BC)的标志。 BC的主要目标是functional cohesion,如果你的模型最终在BC之间产生大量的喋喋不休(换句话说,耦合),那么它可能表明单个BC会更合适。在隔离不同的BC之前,请考虑如何通过分区模块(.NET中的命名空间)来更好地服务您的模型。看看Implementing Domain-Driven Design了解更多。另外,通常情况下,各种查询要求可能会使多个BC在场,实际上,您只需要以不同的方式查看同一个实体。这与将完全不同的实体集合在一起非常不同。考虑使用read-model pattern来解决这个问题。

+0

隔离功能区域是我主要使用有界的上下文,但是我认为你不可能在没有某些实体重叠的情况下做到这一点。我当然不希望在上下文之间允许很多耦合,因为这意味着我错误地将区域分割开来,而不是模式上的问题。 – user1671016

+0

在我的场景中,系统将由多个产品共享一个数据库组成。将会有一些共享的和一些特定于产品的功能,所以我正在努力研究分解这种情况的最佳方式。明确定义有界上下文的想法似乎是分离功能的一种很好的方式,然后使用名称空间来提供该功能的产品范围(产品特定或常用)。这听起来像个好主意吗?许多实体将只读,因此使用有界的上下文允许干净地完成此操作。 – user1671016

+0

如果将域分区为多个BC,则还应该将数据库划分到这些BC的周围,否则可能会导致边界泄漏。问问你自己你是否有共享实体,或者你对实体有不同的观点。 BC可以共享实体_identity_,在这种情况下,一个BC可以将功能“附加”到另一个BC的实体。你能提供关于你的域名的更多细节吗? – eulerfx

1

我也在尝试有界的上下文,并且遇到了模式问题(小?)。我最初创建了两个上下文,一个用于域数据,另一个用于审计类型数据(实体更改审计信息和流程信息)。 最初,我发现数据库仅从一个上下文创建表并忽略另一个上下文。我假定从基本上下文中推导出两个上下文,

public class BaseContext<TContext> : DbContext where TContext : DbContext 

会生成完整的数据库,但似乎没有这样做。

解决此问题的一种方法是创建一个引用所有实体但不将其暴露给模型的“主”上下文。这工作正常,但现在有一个与数据库模式小问题。因为我们的支持人员使用SSMS来调试系统,所以我认为沿着与有界上下文相同的方向改变模式是一个好主意,所以我在主上下文中指定了模式(O​​nModelCreating()override方法与主上下文):

modelBuilder.Entity<Address>() 
      .HasKey(b => new {b.AddressId,b.EffectiveStartDate}) 
      .ToTable("Addresses", "Esr"); 

其中“Esr”是模式。 但是,在尝试使用有界上下文写入数据时,发生错误,指示有界上下文正在使用“dbo”模式。我确信有一种解决方法。我确实有一种唠叨的感觉,认为这可能不值得所有的努力。

当然,有界的上下文给应用程序提供了一个更清晰的感觉,我喜欢构造代码以适应域结构的想法,因为这样可以使整体架构更接近规范,并有助于思考测试。

另一方面,我的同事程序员在编写单个单一的上下文时是否会遇到挑选正确的实体的麻烦?

上下文的分离在应用于支持或UAT领域时非常有用,而且这些人员必须根据整个业务流程来处理应用程序。

+0

有趣的是,当您从流利配置切换到数据注释时,此问题消失。您必须切换所有配置,因为一旦EF看到数据注释,它似乎忽略流利(我留在原地)。我猜它是有效的,因为所有的上下文都使用相同的POCO类,因此您可以在数据注释中定义一个公共的数据库模式。 – Ackroydd

+0

经过多次实验后,我尝试在Repository级别进行逻辑分割(“Bounded Repositories”?)。由于存储库位于dbcontext和模型之间,因此感觉就像正确的结构。唯一的问题是模型的某些部分通常与两个存储库一起工作,因此为了确定应该使用哪一个,我必须宽泛地使用类型参数。结果可行,但不是最好看的代码。 – Ackroydd

1

我们现在正在讨论这个确切的问题,我也看过茱莉亚视频以及研究DDD。我希望我的数据访问能够反映工作单元,但是我们遇到的问题是表名不能用于多个EDMX。

比方说,我有表Customer,CustomerOrder,Order,OrderInventory,Item。 在一个屏幕上,我只想显示客户信息,这样我的EDMX就只有客户。现在另一个用例是我为所有客户开具的发票,在这个用例中,我有Customer,CustomerOrder,Order,OrderInventory和Item。我们得到以下异常: CLR类型到EDM类型的映射不明确,因为多个CLR类型与EDM类型“客户”相匹配。以前发现CLR类型'A.Customer',新发现CLR类型'B.Customer'。

你们如何解决这个错误信息?你是否重命名所有EDMX文件中重复的每张表格?