我刚看过Julie Lermans关于在EF中使用有界上下文的视频(http://www.pluralsight.com/training/Courses/TableOfContents/efarchitecture),我现在正试图找出实现它的最佳方式(使用POCO)。我看到的两个选项是要么有一个edmx模型定义所有内容,然后手工制作DbContexts以包含适当的实体,或者为每个上下文分别使用edmx模型并使用自动创建的DbContexts。
有没有人认为哪个是最好的还是任何利弊?
IMHO: 对于单个模型,它是更少的类和更多的代码重用(虽然这些类是自动创建的,所以实际上它只是手动复制的额外功能),但我会有很多类一个地方和需要专业的类,每个都必须有不同的名称。例如。客户,CustomerForFunctionalityX,CustomerForFunctionalityB。
对于单独的模型,我可以对进入上下文的内容更加严格,因为删除属性不需要是一个全新的实体,我可以根据需要命名所有内容(即所有模型都可以使用客户)即使对象在模型之间有所不同,但是现在每个上下文都有完全不同的实体,即使它们都只是映射到同一个表 - 这也使得在上下文之间传递它们变得更加困难(但是这也不需要通常情况下,它意味着上下文被定义为错误。)
答案 0 :(得分:1)
我也在尝试有限的上下文,并遇到了一个(小?)问题的模式。我最初创建了两个上下文,一个用于域数据,一个用于审计类型数据(实体更改审计信息和进程信息)。 最初,我发现数据库只从一个上下文创建表而忽略了另一个上下文。我假设从基础上下文中导出两个上下文,
public class BaseContext<TContext> : DbContext where TContext : DbContext
会生成完整的数据库,但似乎没有这样做。
解决此问题的一种方法是创建一个引用所有实体的“主”上下文,但不将其公开给模型。这工作正常,但现在db模式存在一个小问题。
由于我们的支持人员使用SSMS来调试系统,我认为以与有界上下文相同的方式更改模式是个好主意,因此我在主上下文中指定了模式(OnModelCreating()覆盖方法与主背景一起):
modelBuilder.Entity<Address>()
.HasKey(b => new {b.AddressId,b.EffectiveStartDate})
.ToTable("Addresses", "Esr");
其中“Esr”是架构。 但是,在尝试使用有界上下文写入数据时,会发生错误,指示有界上下文使用“dbo”架构。我相信这有办法解决这个问题。我有一种唠叨的感觉,这可能不值得所有的努力。
当然,有界的上下文给应用程序带来了更清晰的感觉,我喜欢构造代码以适应域结构的想法,因为这使整体架构更接近规范并且在考虑测试时有所帮助。
另一方面,我的同事程序员在针对单一的整体上下文进行编码时是否会选择正确的实体?
当在支持或UAT领域应用时,上下文分离更有用,这些人必须在整个业务流程方面使用应用程序。
答案 1 :(得分:1)
我们现在正在讨论这个确切的问题,我也看过Julies视频以及研究DDD。我希望我的数据访问能够反映工作单元,但我们遇到的问题是表名不能用于多个EDMX。
假设我有表Customer,CustomerOrder,Order,OrderInventory,Item。 在一个屏幕上,我只想显示客户信息,因此我的EDMX只有客户。现在另一个用例是我为客户开发的所有发票,在这个用例中我有Customer,CustomerOrder,Order,OrderInventory和Item。我们得到这个例外: CLR类型到EDM类型的映射是不明确的,因为多个CLR类型与EDM类型“Customer”匹配。以前发现CLR类型'A.Customer',新发现的CLR类型'B.Customer'。
你们是如何解决此错误消息的?您是否重命名在所有EDMX文件中重复的每个表?
答案 2 :(得分:0)
我建议你阅读有限的背景以及他们试图解决的问题。从有界上下文definition:
明确定义模型适用的上下文。根据团队组织,应用程序特定部分的使用情况以及代码库和数据库模式等物理表现形式明确设置边界。保持模型在这些范围内严格一致,但不要被外界的问题分心或混淆。
拥有单个EDMX模型会违反该显式边界。你可以想象当来自不同环境的团队在同一个EDMX模型上工作时可能发生的摩擦。 但是,在您的情况下,您可能会觉得上下文之间的显式边界和集成的成本太高。使用Shared Kernel可以让您在上下文之间共享EDMX模型。
答案 3 :(得分:0)
但现在每个上下文都有完全不同的实体,即使它们是 所有只是映射到同一个表
这表明您可能实际上不需要多个有界上下文(BC)。 BC的主要目标是functional cohesion,如果你的模型最终在BC之间有很多喋喋不休(换句话说是耦合),那么很可能表明单个BC更合适。在隔离不同的BC之前,请考虑通过分区到模块(.NET中的命名空间)来更好地服务您的模型。有关详细信息,请查看Implementing Domain-Driven Design。
此外,通常情况下,各种查询要求可能会使多个BC看起来像现实一样,实际上您只需要不同的方式来查看同一个实体。这与完全不同的实体在一起非常不同。考虑使用read-model pattern来解决此问题。