【问题标题】:DAL Repository pattern joins using dapperDAL 存储库模式使用 dapper 连接
【发布时间】:2023-03-21 15:25:02
【问题描述】:

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

我的数据库表如下

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?

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

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

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

编辑:

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

【问题讨论】:

    标签: .net repository-pattern data-access-layer


    【解决方案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 适用于热爱数据库并经常与之交谈的人。回购可能会相互重叠。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-22
      • 2012-07-13
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      相关资源
      最近更新 更多