2016-12-19 46 views
1

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

我的数据库表如下所示

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中显示的那样,还是有更好的方法?
  2. 我的关系表应该得到他们自己的pocos吗?如果是这样,是否只有当他们有额外的数据,如isActive和用户/账户特定的设置。
  3. 在我的仓库里,我不确定哪个仓库在处理关系时应该处理特定的请求。
  4. 我应该有另一个账户/用户关系的回购?

批评,链接,欢迎大家的到来谢谢。

编辑:

附加说明:应该提到。我想让用户/账户在一起的原因是因为他们将在一个网格中,我们可以激活/停用并修改用户或其账户的值。

回答

1

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

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

A 4创建另一个存储库来分别处理帐户。

+0

A1&3之前应该说过,但是将它用于网格,因此所有用户都必须获得所有帐户。 10k以上的通话表现会很慢。好主意我可能会在其他地方使用。 A 2.我在哪里可以找到tblAccountUser.IsActive,以查看用户是否对特定帐户有效。 A4。有一个帐户是你的意思是一个tblAccountUsers? – ozz

+0

A 2在AccountRepository中。您可以筛选非活动账户或将IsActive作为账户对象中的一个属性返回。 A 4我的意思是AccountRepository。创建像GetAccountsByUserId – detale

+0

方法我试着做你建议通过不活动/活动过滤,并单独显示它们,这是一种混乱,因为我们需要能够通过user.email和account.name搜索取决于哪个更相关。 IsActive是帐户和用户帐户关系的属性,这使得它独一无二。由于存在额外的列而不仅仅是(AccountID,UserID),我被建议在其他地方为关系创建poco。到目前为止哪个工作更好。 – ozz

0

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

一旦你有你的回购类,提取它的接口。粗略地说,1个存储库对应于1个查询对应于1个平坦结果集。在存储库中没有加入的概念。数据库中的连接可能与您的应用程序代码中的集合相对应:用户的实例将包含列表或词典或IEnumerable of Accounts,并且不会停止具有用户集合的帐户实例。但用户和帐户不是存储库。它们可能是由存储库返回的POCO。更通常的是,它们被定义在应用程序的另一个层中,并封装数据层返回的POCO。这带来了明显的一致性问题,您可以自行解决:-)存储库模式不会帮助您。如果用户在用户屏幕上选择帐户,那么您的User对象可能会调用某个存储库某处插入AccountUser的方法。如果您在账户屏幕上选择用户,则账户对象可能会调用相同的方法。该方法可能在UserRepo,或AccountRepo或SomeOtherRepo一起。

尝试和使用Dapper来模拟实体框架将是一个错误。不要想象你可以编写一次你的仓库,然后永远不要碰它们。 Dapper适用于热爱数据库的民众,并经常与之交流。 Repos可能会相互重叠。