DAL 存储库模式使用 dapper 连接

Posted

技术标签:

【中文标题】DAL 存储库模式使用 dapper 连接【英文标题】:DAL Repository pattern joins using dapper 【发布时间】:2017-05-04 22:14:32 【问题描述】:

我正在尝试实现存储库模式,我发现的所有示例都非常简单(忽略连接)或使用实体框架。

我的数据库表如下

tblUser id, fname, lname, email, password, dateAdded
tblAccount id, name, isActive, dateAdded
tblAccountUser userId, accountId, isActive, dateAdded

一个用户可以有多个帐户,一个帐户可以有多个用户。 tblUserAccount 有一个布尔值,它告诉我们用户是否对该帐户处于活动状态以及何时添加用户。

我的 pocos 直接映射到具有关系的附加属性的表。有没有更好的方法来完成这部分?我想不出更好的方法让我的存储库返回 GetUsersWithAccounts(userId) 之类的关系。

tblUser 
    guid id, 
    string fname, 
    string lname, 
    string email, 
    string password, 
    date dateAdded, 
    IList<tblAccount> accounts


tblAccount 
    guid id, 
    string name, 
    bool isActive, 
    date dateAdded, 
    IList<tblUser> users


//should i have a tblAccountUser poco with something like
//tblUser user, tblAccount account, bool isActive, date dateAdded

我有以下存储库:

UserRepository 
    Add()...
    ...
    tblUser GetById(guid userId)  
    IEnumberable<tblUser> GetAll() 

    //was unsure if Account repo should retrieve a user's accounts or if the user repo should.
    //using uow.User.GetAccounts(user.id) seems natural but please feel free to let me know what you think
    IEnumberable<tblAccount> GetAccounts(guid userId) 

    //this is the one i was really unsure about
    //this would return tblUser obj with its tblUser.Accounts filled.
    IEnumberable<tblUser> GetAllWithAccounts()


AccountRepository
    Add()
    ...
    AddUser(guid userId) //only adds relation to tblAccountUser Makes sense? 



//Should i have a repository for the Account <-> User relations?

问题无处不在,总结一下:

    从我的存储库返回 pocos 时,我应该如何返回关系。正如我在上面的 pocos 中展示的那样,还是有更好的方法? 我的关系表应该有自己的 pocos 吗?如果是这样,是否只有当他们有额外的数据(如 isActive 和用户/帐户特定设置)时。 在我的存储库中,我不确定哪个存储库应该处理关系方面的特定请求。 我应该为帐户/用户关系创建另一个存储库吗?

欢迎批评、链接、帮助,谢谢。

编辑:

补充说明:应该提到。我想将用户/帐户放在一起的原因是因为它们将位于一个网格中,我们可以在其中激活/停用和修改用户或其帐户的值。

【问题讨论】:

【参考方案1】:

A 1 & 3 当您的 UserRepository 方法返回一个 tblUser 对象时,它不需要填充帐户。所有非集合属性都应由 UserRepository 处理。 在 accounts 属性的 getter 中,调用 AccountRepository 中的方法来进行数据库调用,以在第一次调用 getter 时获取用户的所有帐户。

A 2 关系表不需要自己的 pocos。

A 4 创建另一个存储库以单独处理帐户。

【讨论】:

A1&3 之前应该说过,但将其用于网格,因此所有用户都必须获得所有帐户。超过 10k 次调用时性能会很慢。好主意,我可能会在其他地方使用。 A 2. 我在哪里可以找到 tblAccountUser.IsActive 以查看用户是否对特定帐户处于活动状态。 A4。帐户有一个,您的意思是 tblAccountUsers 有一个吗? A 2 在 AccountRepository 中。您可以过滤非活动帐户或将 IsActive 作为 Account 对象中的属性返回。 A 4 我的意思是 AccountRepository。创建 GetAccountsByUserId 等方法 我尝试按照您的建议按非活动/活动过滤并分别显示它们,这有点混乱,因为我们需要能够根据 user.email 和 account.name 进行搜索哪个更相关。 IsActive 是帐户和用户帐户关系的属性,这使其独一无二。由于存在其他列而不仅仅是(AccountID,UserID),因此建议我在其他地方为该关系创建一个 poco。到目前为止效果更好。【参考方案2】:

也许部分答案是减压。存储库模式的重要部分是您有一个包装数据库调用的类,它返回 pocos,而不是 ADO 类,让您进行单元测试。装饰部分是将插入/更新/删除方法与“选择”方法组合在同一类中,让您忘记您正在处理数据库。为什么要忘记是另一个问题。

一旦你有了你的 repo 类,解压它的接口。粗略地说,1 个存储库对应于 1 个查询对应于 1 个平面结果集。没有加入in 存储库的概念。数据库中的联接可能对应于应用程序代码中的集合:User 实例将包含一个 List 或 Dictionary 或 IEnumerable 帐户,这不会阻止具有用户集合的 Accounts 实例。但是用户和帐户不是存储库。它们可能是存储库返回的 POCO。更常见的是,它们定义在应用程序的另一层,并封装数据层返回的 POCO。这带来了明显的一致性问题,留给您解决 :-) 存储库模式在这里对您没有帮助。如果您的用户在用户屏幕上选择帐户,您的用户对象可能会在某个存储库的某个地方调用插入到 AccountUser 中的方法。如果您在 Account 屏幕上选择 Users,Account 对象可能会调用相同的方法。该方法可能在 UserRepo、AccountRepo 或 SomeOtherRepoAltogether 中。

尝试使用 Dapper 来模拟实体框架是错误的。不要以为您可以编写一次存储库,然后再不碰它们。 Dapper 适用于热爱数据库并经常与之交谈的人。回购可能会相互重叠。

【讨论】:

以上是关于DAL 存储库模式使用 dapper 连接的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 petapoco 创建 DAL [关闭]

C# Dapper基本三层架构使用 (DAL)

如何解决 Dapper - UnitOfWork 事务错误

具有存储库模式的实体框架 DAL、BLL

存储库模式:DAL 或 BLL [关闭]

DAL 中的实体框架存储库模式,如何实现更新功能?