复杂的查询应该写在Repository层还是Service层?我计划迁移数据访问层以使用存储库模式和工作单元。我知道存储库将帮助我轻松地将持久存储(数据库、集合等)和EF等技术更改为MongoDB。所以我注意到存储库实现的一些关键点,例如:ReturnIEnumerable而不是IQueryableRepository应该只负责CRUD操作Repository方法的返回类型应该是模型(实体)RepositorythatonlyimplementsaggregaterootifIareinproject在项目中应用这些关键点中的实现存储库,我完全忘记了如何处理与多个实体相关的复杂查询。目前我已经拥有的是BLL库上的许多服务类,它们将直接绑定到EF的DbContext和DbSet以及一些像这样的验证:publicIEnumerableGetProjectWithDetails(){//Validation//Logging//可以是任何需要的逻辑查询数据前。数据库上下文。项目。Where(p=>//此处的多个条件遵循业务规则//条件将需要检查另一个实体(任务、阶段、员工...),例如://1.项目的任务状态为“进行中”..等//2.项目有employeeid1,2,3..//3.项目有任务在某个特定日期开始。//4....).Select(p=>newProjectDTO{Label=p.Label,Phase=newPhaseDTO{Label=p.Phase.Label,Tasks=p.Phase.Tasks.Select(t=>newTaskDTO{//一些相关属性})}})。列表();我目前正在使用数据传输对象(DTO)作为模型和控制器上的视图模型之间的中间类,并使用Mapper来映射属性。如果我在上述存储库中保留关键注释,我需要多次往返数据库以获取数据,它将返回整个模型而不是有用的列。但是,如果我将这些方法迁移到存储库,我将打破存储库模式,因为它将包含业务逻辑和返回类型而不是模型。所以问题是在这种情况下我该怎么办?请给我一些建议,让我走上正轨。太感谢了。使用存储库模式的好处之一是隐藏复杂的查询,您应该将存储库视为内存中对象的集合(martinfowler):存储库在域和数据映射层之间进行调解,就像内存中的域对象收集一样。客户端对象以声明方式构造查询规范并将其提交到存储库以满足要求。可以在简单的对象集合中添加和删除对象,或者从存储库中删除对象,存储库封装的映射代码将在幕后执行适当的操作。从概念上讲,存储库封装了数据存储中持久保存的对象集以及对它们执行的操作,提供了持久层的更面向对象的视图。存储库还支持域和数据映射层之间完全分离和单向依赖的目标https://martinfowler.com/eaaCatalog/repository.html这取决于意见和用例,但我个人不同意你提到的一些观点.同意返回IEnumerable而不是IQueryable。返回IQueryable违背了存储IQueryable的基本目的。网上有很多文章解释了如何制造比解决方案更多的问题。虽然,我学会了永不言败。请参考这个,这个或这个。或者只是搜索谷歌。存储库应仅在征得同意的情况下负责CRUD操作。使用简单的CRUD,它也可以进行复杂的读写操作。我的经验告诉我们,在特殊情况下,如果要在RDBMS端实现,就必须将部分业务逻辑放在repository中。这没有对错之分。如果您知道自己在做什么,那应该没有问题。存储库方法的返回类型应该是模型(实体)如果你不使用DDD那么是的。否则,这是一个实施决定。使用像EF或NHibernate这样的完整ORM,最好直接返回域模型而不是每个表的实体实例。总是建议Repository应该返回DomainModel。这样,将从RDBMS返回的数据映射到域模型(反之亦然)成为存储库的责任。这避免了将持久性问题泄露到存储库之外的需要,而使应用程序持久性的其余部分一无所知。但是,并非每个应用程序都实现DDD。数据库设计一对一映射的许多小型应用程序设计实体。在这种情况下,存储库可以返回实体(相当于您的表和字段)本身,并且映射成为调用代码的责任。或者,存储库可以映射必要的模型并返回模型本身。由于上述问题,强烈建议不要这样做。有了这个,你不得不放弃ORM提供的一些功能。所有这一切都取决于你的问题是什么,你的设计目标是什么,你的应用程序的大小和其他设计模式的实现等。这就是为什么它成为一个设计决策。仅实现聚合根的存储库同意是否与DDD一起使用。如果没有,则有多个选项可用,例如每个表一个存储库。同样,取决于用例。关于复杂的查询存储库不必只实现简单的CRUD方法。它还可能返回复杂的对象图。它可能会进行复杂的查询。也就是说,使用Get、GetById等简单方法,也可以使用GetTopBrokenVehicles(vehicleType,top)等复杂方法。如果您为复杂查询编写单独的方法,那绝对没问题。挑战在于您如何接受必要的参数。您可以接受内联参数或构建一个单独的简单输入参数类。下面是Repository和UoW的示例代码。以上就是C#学习教程:复杂查询应该写在Repository层还是Service层?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
