Domain driven design 您如何处理DDD和EF4

Domain driven design 您如何处理DDD和EF4,domain-driven-design,entity-framework-4,Domain Driven Design,Entity Framework 4,我在尝试将DDD应用于EF4(在ASP MVC2上下文中)时遇到了几个问题。如蒙告知,不胜感激 首先,我开始使用POCO,因为在很多情况下对ObjectContext的依赖不是很舒服 去POCO解决了一些问题,但我对NHibernate的体验并不习惯 我想知道是否可以使用designer,不仅生成实体,还生成值对象(ComplexType?)。如果我的意思是值对象是一个类,它有一个没有任何设置属性的向量(需要T4修改吗?) 我发现向贫血实体添加行为的唯一方法是创建扩展edmx生成的部分类。我对这

我在尝试将DDD应用于EF4(在ASP MVC2上下文中)时遇到了几个问题。如蒙告知,不胜感激

首先,我开始使用POCO,因为在很多情况下对ObjectContext的依赖不是很舒服

去POCO解决了一些问题,但我对NHibernate的体验并不习惯

我想知道是否可以使用designer,不仅生成实体,还生成值对象(ComplexType?)。如果我的意思是值对象是一个类,它有一个没有任何设置属性的向量(需要T4修改吗?)

我发现向贫血实体添加行为的唯一方法是创建扩展edmx生成的部分类。我对这种方法不满意

我不知道如何用一个edmx创建多个存储库。目前,我正在使用分部类对每个聚合的方法进行分组。每个组实际上都是一个存储库

最后一个问题是关于IQueryable的。它应该暴露在存储库之外吗?如果我参考ble的书,存储库应该是一个执行单元,不应该公开像IQueryable这样的东西。你觉得怎么样

谢谢你的帮助


Thomas

可以使用POCO,但请注意,
EntityObject
不需要
ObjectContext

是的,复杂类型是值对象,可以在设计器中生成它们。选择实体的多个属性,单击鼠标右键,然后选择“重构为复杂类型”

我强烈建议将业务方法放在它们自己的类型中,而不是放在实体上。“贫血”类型可能是一个问题,如果你必须维持他们,但当他们编码,他们几乎不是一个维护问题。将业务逻辑与实体类型分离,可以使业务规则和数据模型独立发展。是的,如果必须混合这些关注点,则必须使用分部类,但我不认为分离模型和规则是一件坏事


我认为存储库应该公开
IQueryable
,但您可以很好地证明域服务不应该公开。人们经常试图将他们的存储库构建到域服务中,但请记住,存储库的存在只是为了抽象出持久性。像安全性这样的问题应该在域服务中解决,您可以这样认为,
IQueryable
给消费者带来了太多的权力。

我认为在存储库之外公开IQueryable是可以的,只是因为不这样做可能会带来不必要的限制。如果只通过
GetPeopleByBirthday
GetPeopleByLastName
等方法公开数据,那么当有人按姓氏和生日搜索某人时会发生什么情况?你是把所有姓“史密斯”的人都拉进来,然后线性搜索你想要的生日,还是创建一个新方法
GetPeopleByBirthdayAndLastName
?那个可怜的倒霉家伙必须执行QBE表格怎么办

当对域进行特殊查询的唯一方法是生成SQL时,确保自身安全的唯一方法是提供检索和更改数据的特定方法。现在我们有了林克,没有理由戴上手铐。任何人都可以提交查询,您可以安全地执行它,而无需担心

当然,您可能会担心用户可能会查看其他人的数据,但这很容易缓解,因为您可以限制您提供的数据。例如:

public IQueryable<Content> Content
{
    get { return Content.Where(c => c.UserId == this.UserId); }
}
公共可查询内容
{
获取{return Content.Where(c=>c.UserId==this.UserId);}
}
这将确保用户可以获得的唯一
内容
行是那些具有其
用户ID的行


如果您关心的是数据库的负载,那么您可以执行诸如检查查询表达式以进行表扫描之类的操作(访问不带
Where
子句的表,或者在
Where
子句中不带索引列的表)。当然,这不是小事,我不会推荐它。

我已经有一段时间没有问这个问题了,也没有机会自己去做了

我认为将IQueryable暴露在DAL层之外并不是一个好的做法。它带来了更多需要解决的问题。我说的是大型MVC应用程序。首先,重构更为困难,许多开发人员从视图中使用IQueryable实例,在解决IQueryable时,连接已经被释放,这一事实让他们感到困惑。性能问题,因为所有数据库都经常查询一组给定的结果等等


我宁愿从我的存储库中公开Ienumerable,相信我,它为我省去了很多麻烦。

谢谢你的回复。通常,我对实体使用明显的行为方法。当不明显时,我会为此创建一个服务。你如何解决这一点?如果存储库公开IQueryable,因此无法保证它将在任何时候被处置,或者如果它被处置,则在将IQueryable转换为List或Enumerable时会出现问题,因为连接将已关闭。关于处置连接,my domain services的公共面是一个工作单元对象。工作单元实现IDisposable。工作单元保留对ObjectContext实例的私有引用,该引用通过构造函数注入传递到存储库。在我的例子中,工作单元是由ASP.NET MVC控制器消耗的,在视图呈现之前,这些控制器本身不会被处理,因此在正确的时间处理所有内容是很自然的;我从来不需要考虑它。关于将业务方法放在何处,我发现将所有内容放在域服务中比将一些放在域服务中或其他放在不同的位置更自然。当您使用ADO.NET data services/Astoria等数据服务时,这一点尤为重要。关于IQueryable问题,请参见以下内容: