0

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

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

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

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

回复卢克·麦格雷戈:

一种)

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

所以导航属性应该联系上下文?!但是由于导航属性也存在于域模型中,我们难道不能说通过直接联系上下文,它们也会违反PI吗?

b) 根据Fowler 的关于 Data Mapper 的 PEAA 章节,可以从Data Mapper中提取域代码所需的任何方法到接口类中,然后域代码可以使用该接口类。当使用EF而不是手写的Data Mapper时,如何以不违反PI的方式准确地做到这一点?

谢谢你

4

2 回答 2

3

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

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

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

于 2012-10-03T19:09:52.607 回答
2

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

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

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

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

前提是这Orders是一个聚合根。如果不是,您可以使用域层服务,该服务转向基础设施层服务进行查询,或者直接从他们自己的聚合根中询问订单。

于 2012-10-04T10:17:51.630 回答