Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance DDD和实体框架、过滤器_Performance_Entity Framework_Domain Driven Design - Fatal编程技术网

Performance DDD和实体框架、过滤器

Performance DDD和实体框架、过滤器,performance,entity-framework,domain-driven-design,Performance,Entity Framework,Domain Driven Design,因此,当我们谈论过滤和查询时,DDD必须遵循的方法让我很为难。从这个问题中,我可以看到用户的过滤应该在获得所有产品后进行。可接受答案中的代码为: Products products = /* get Products repository implementation */; IList<Product> res = products.BoughtByUser(User user); 但从我对DDD的实际了解来看,这是错误的,因为这种逻辑应该在产品本身内部 因此,如何处理这种情况?

因此,当我们谈论过滤和查询时,DDD必须遵循的方法让我很为难。从这个问题中,我可以看到用户的过滤应该在获得所有产品后进行。可接受答案中的代码为:

Products products = /* get Products repository implementation */;
IList<Product> res = products.BoughtByUser(User user);
但从我对DDD的实际了解来看,这是错误的,因为这种逻辑应该在产品本身内部


因此,如何处理这种情况?

根据您的链接,
产品
类是存储库,只是命名时没有“存储库”后缀

您认为筛选应该在数据库中是正确的,只是因为您在域中而看不到它

第一种和第二种方法是相同的。区别在于,第一种语言更符合DDD,因为
通用语言的正确使用

// First example
// Take note, the products IS the repository
IList<Product> productsByUser = products.BoughtByUser(User user);

// Second example
IList<Product> productsByUser = productsRepository.Find(p => p.User.Id == userId);
//第一个示例
//请注意,产品就是存储库
IList productsByUser=products.BoughtByUser(用户用户);
//第二个例子
IList productsByUser=productsRepository.Find(p=>p.User.Id==userId);
如果你深入到数据访问层,你可以看到你正在谈论的过滤

public IList<Product> BoughByUser(User user)
{
    IList<Product> products = this.dbContext.Products.Find(p => p.User.Id == user.ID);

    return products;
}
公共IList BoughByUser(用户)
{
IList products=this.dbContext.products.Find(p=>p.User.Id==User.Id);
退货产品;
}

我同意约罗的回答。根据评论,产品确实是一个存储库。 关于底层数据结构的性能与将领域知识保留在应用程序中的问题可以进一步探讨。 数据库在过滤和查询数据方面非常出色,它们为此进行了优化,而对于我们来说,仅仅“将我们的知识保留在领域中”是天真的

您的示例显示了存储库专门化,这很好,尽管很详细。 该搜索的逻辑由该调用封装,只要调用该方法的接口在域中,实现在数据层中,一切都很好。 实际上,调用可以是执行非常复杂操作的存储过程。(在这种情况下,是的,您的一些逻辑已经逃离了这个领域,但是您做出了一个有意识的决定,如果您引入了另一种数据技术,您将不得不再次实现该功能。)

还有另一个选择。。。 我们可以将搜索的逻辑封装在一个规范()中,并将规范从域逻辑代码传递到我们的存储库,存储库将解释规范并执行查询。 这使得我们的域忘记了底层数据结构是如何工作的,但它控制了搜索条件是什么


我通常会发现自己实现了存储库专门化的混合,并拥有一个基础存储库,它接受ISpecification以实现更轻量级的查询。

这不是您问题的直接答案(Yorro的答案是正确的),但它可能有助于您更好地理解DDD。这是一个“错误的方式,回头”的答案

您的视图不需要域规则;不需要100万个孩子或100万个实体的集合。因此,您不需要“绕过”产品存储库,因为您应该拥有带有“视图存储库”的“视图服务”,它允许您查询(和分页等)视图的持久化数据

需要更新/插入/删除时,应使用聚合/实体应用域规则


一旦用户从100万列表中选择一个或多个产品并按下删除按钮,您应该使用产品存储库检索所选产品的聚合/实体,应用删除规则和不变量并持久保存。

如果我在我的
RepositoryBase
中有一个
Find
方法,该方法需要一个表达式作为参数,并从域中的实际
ProductService
类调用传递lambda的
Find
方法。这是一个好方法吗?我的意思是,逻辑不在
Product
(实体)类本身内部,而是在
ProductService
内部,它也是域的一部分。是的,这很好。取决于系统将有多大,您仍然可以考虑规范的方法,并将这些搜索表达式封装在规范中。如果你仔细阅读ISpecification,你会注意到正是执行和/或等的能力,以及有效地链接它们,使它们如此强大。表达式已经非常强大了,使用它们作为规范模式的底层查询机制非常好。(看看约瑟夫·阿尔巴哈里(joseph albahari)写的《林奇奇》(LinqKit)。他在博客上讲述了自己是如何写的,这提供了一些非常有价值的见解。)同意。我会这样做:如果我需要对单个对象的属性进行验证,我会将此方法放在实体中。否则,如果我需要基于一个查询字符串来查询多个对象,我将使用存储库方法。你觉得怎么样?
public IList<Product> BoughByUser(User user)
{
    IList<Product> products = this.dbContext.Products.Find(p => p.User.Id == user.ID);

    return products;
}