在存储库模式中加载子记录

Kei*_*ler 12 c# design-patterns domain-driven-design repository linq-to-sql

使用LINQ TO SQL作为基于存储库的解决方案的基础.我的实现如下:

IRepository

FindAll
FindByID
Insert
Update
Delete
Run Code Online (Sandbox Code Playgroud)

然后我有扩展方法,用于查询结果:

WhereSomethingEqualsTrue() ...
Run Code Online (Sandbox Code Playgroud)

我的问题如下:

我的用户存储库有N个角色.我是否创建了角色存储库来管理角色?我担心,如果我走这条路,我最终会创建几十个存储库(每个表几个,除了连接表).每个表的存储库是否常见?

wom*_*omp 32

如果要构建特定于一个实体(表)的存储库,以便每个实体都具有上面列出的IRepository接口中的方法列表,那么您实际所做的是Active Record模式的实现.

绝对不应该为每个表都有一个Repository.您需要识别域模型中的聚合以及要对其执行的操作.用户和角色通常紧密相关,通常您的应用程序将与它们一起执行操作 - 这需要一个单独的存储库,以用户及其密切相关的实体为中心.

我猜你在帖子中看到过这个例子.此示例的问题是所有存储库在基础级别共享相同的CRUD功能,但他没有超出此范围并实现任何域功能.该示例中的所有存储库看起来都是相同的 - 但实际上,真实的存储库并不都看起来相同(尽管它们仍然应该是接口的),每个存储库都会有特定的域操作.

您的存储库域操作应该更像:

userRepository.FindRolesByUserId(int userID)
userRepository.AddUserToRole(int userID)
userRepository.FindAllUsers()
userRepository.FindAllRoles()
userRepository.GetUserSettings(int userID)
Run Code Online (Sandbox Code Playgroud)

等等...

这些是您的应用程序想要对基础数据执行的特定操作,而存储库应提供该操作.可以把它想象成Repository表示您将在域上执行的原子操作集.如果您选择通过通用存储库共享某些功能,并使用扩展方法扩展特定存储库,那么这种方法可能适用于您的应用程序.

一个好的经验法则是,您的应用程序很少需要实例化多个存储库来完成操作.确实需要,但如果您的应用程序中的每个事件处理程序都只是为了获取用户的输入并正确实例化输入所代表的实体而处理六个存储库,那么您可能遇到了设计问题.