我正在尝试使用 Dapper 实现存储库模式,但它似乎使我的数据访问变得非常复杂。当我需要相同的查询但具有不同的选择参数时,以及当我想返回完整模型的投影/子集时,尤其如此。
例如,我最终得到的是:
GetUserById(), GetUserByUsername(), GetUserByLastName(), GetUserByFirstName(), ...
然后假设我还想只返回完整用户模型的一个子集,比如返回用户名、名字、姓氏和会计部门的薪水,我会有这些方法:
GetUserForAccountingDTOById(), GetUserForAccountingDTOByUsername(), GetUserForAccountingDTOByLastName(), ...
如果我有其他一些具有类似搜索要求的 DTO,问题只会在
O(n*m)
中变得越来越大,其中 n
是选择标准的数量,m
是子集的数量。
显然在实践中,我们不需要每个
n
搜索条件的子集,但即使每个 DTO 只有 2 个子集,它也会变得乏味且重复。
以下是我想到的一些解决方案,但我认为没有完全解决问题:
1- 投影问题的一个简单解决方法是消除返回的完整模型的投影/子集,但随后我们将查询大量不必要的数据,尤其是对于大型查询。此外,我们仍然有很多搜索/选择标准的问题。
2-对于选择标准,我们可以传递一个具有所有规格的对象,如
{Id: x, Username: null, FirstName: null, ...}
,然后动态生成SQL。但是,这非常限于基本的WHERE Id = x
选择。如果我们有更复杂的选择,我们将再次需要很多非常相似的自定义方法,让我们回到同样的问题。
我能想出的唯一能完全解决这个问题的解决方案是放弃 Dapper,直接在没有存储库的服务层中使用 EF。缺点是我将数据访问与服务层耦合,但 EF 已经是数据访问的抽象。
我个人更喜欢使用 Dapper 和编写 SQL 来访问数据,并且希望更好地实现存储库模式来解决这个问题。或者,这个问题可能源于我做错的其他事情......