以下代码是否违反了持久性无知规则

时间:2012-10-03 19:06:53

标签: entity-framework design-patterns orm domain-driven-design

a)域实体不应包含与持久性相关的代码,因此它们应该是 Persistence Ignorant PI 。但假设域模型 DM 是使用实体框架设计的,并假设服务层执行CRUD操作POCO 域实体通过 Linq-to-Entities ,我们认为服务层直接或通过域访问DAL模型

class CustomerService
{
       public string doSomething( ... )
       {
                ...
                var customer = context.Customers.Where( ... );
                ...
        }
       ...
}

b)在 DM 中使用 Linq-to-Entities 是否违反 PI 规则?例如,以下Customer实体是否违反了PI:

class Customer
{
       public string InterestedWhatOtherCustomerOrdered( ... )
       {
                ...
                var orders = context.Orders.Where( ... ); // does this violate PI rule?
                ...
        }
       ...
}

回复Luke McGregor:

A)

  

是的,因为它直接引用了上下文。一个更好的方法   是使用Customer上的内部导航属性来执行   同样的行动,

那么导航属性应该联系上下文?!但由于导航属性也位于域模型中,我们不能再认为通过直接联系上下文,它们也会违反 PI 吗?

b)根据 Fowler关于Data Mapper的PEAA章节,可以从 Data Mapper 中提取域代码所需的任何方法到接口类中,哪个域然后代码可以使用。如果使用 EF 而不是手写的 Data Mapper ,我们不会违反 PI ?< / p>

谢谢

2 个答案:

答案 0 :(得分:3)

是的,因为它直接引用了上下文。更好的方法是使用Customer上的内部导航属性来执行相同的操作,

class Customer
{
       public string InterestedWhatOtherCustomerOrdered( ... )
       {
                ...
                var orders = this.Orders;
                ...
        }
       ...
}

或为此函数创建单独的查询类。

答案 1 :(得分:2)

a)DDD中有不同类型的服务。域层服务不应该引用实体框架上下文,因为它会将域与特定的持久性方式紧密耦合 - 与域实体相同,见下文。相比之下,应用程序层服务可以使用上下文(例如调用SaveChanges()),因为它知道当前的工作单元,何时应该保留

b)正如Luke所说,是的,它确实违反了PI,因为实体框架上下文是特定于持久性的。在您的实体中,您应该使用持久性无关的方式获取所需的订单。

我不太明白你的InterestedWhatOtherCustomerOrdered()方法做什么(为什么要返回一个字符串?...)但是你可能有:

class Customer
{
       public string InterestedWhatOtherCustomerOrdered( ... )
       {
                ...
                var orders = OrderRepository.GetOtherCustomerOrdersByInterest(...);
                ...
        }
       ...
}

前提是Orders是聚合根。如果不是,您可以使用域层服务转为基础架构层服务进行查询,或者直接从自己的聚合根中询问订单。

相关问题