Linq to sql 数据存储库-业务对象?

Linq to sql 数据存储库-业务对象?,linq-to-sql,repository-pattern,Linq To Sql,Repository Pattern,我正在读《ASP.NET 3.5社交网络-安德鲁·西默》一书,当他使用存储库访问数据时,我感到困惑 以下是他的代码的想法: public interface IAccountRepository { Account GetAcountByID(int acId); void SaveAccount(Account account); List<Account> GetAllAccounts(); } public class AccountRepositor

我正在读《ASP.NET 3.5社交网络-安德鲁·西默》一书,当他使用存储库访问数据时,我感到困惑

以下是他的代码的想法:

public interface IAccountRepository
{
  Account GetAcountByID(int acId);
  void SaveAccount(Account account);
  List<Account> GetAllAccounts();      
}

public class AccountRepositoryLINQ : IAccountRepository
{
  Account GetAcountByID(int acId){
    ..... LINQ query ..... 
    ...... return.....
  }
  void SaveAccount(Account account){
    ..... LINQ ..... 
  }
  List<Account> GetAllAccounts(){
    ..... LINQ query ..... 
    ...... return.....
  }
}
公共接口存储库
{
账户GetAcountByID(int-acId);
作废储蓄账户(账户);
列出GetAllAccounts();
}
公共类AccountRepositoryLINQ:IAccountRepository
{
帐户GetAcountByID(int acId){
…LINQ查询。。。。。
……返回。。。。。
}
作废储蓄账户(账户){
……林克。。。。。
}
列出GetAllAccounts(){
…LINQ查询。。。。。
……返回。。。。。
}
}
类“Account”是在“LINQ到SQL类”上自动生成的类

我看到的一些问题:

我为我的业务层、GUI等编写代码。。。稍后,数据库中的表Accounts发生更改(例如:更改一列的名称),然后我需要重建“LINQ到SQL类”,并且由于我的“Account”对象发生了更改,我的所有代码层都需要重新编码

如果我需要其他存储库(MySQL、Oracle、XML、其他),我将使用什么“Account”类

怎么办?

  • 我不应该使用自定义帐户类吗?这将在所有应用程序层中使用
  • 如何将LINQ映射到我的自定义帐户类?
    • 使用简单的“myClass.Name=linqClass.Name;”???
      • 如果我需要“映射”所有类,这不是在消耗机器资源吗
      • 有没有最简单/最轻松的方法
      • 这是正确的方法吗?还有别的办法吗
    • 良好的本能

      我的建议是抽象出LinqToSQL对象,并创建一组业务域对象。然后,存储库可以查询所需的数据,并将它们映射到应用程序使用的域对象,然后返回这些域对象。现在,您的数据访问层已与应用程序解耦,您现在可以执行列出的所有操作


      映射可能是一件痛苦的事情,所以看看类似于这样的工具来完成这一点。

      我个人使用NHibernate和FluentNHibernate的组合,并将我的域(业务对象)与所有其他事物分开。我使用来自其他层(如GUI)的消息到我的域,域中有一个处理程序,该处理程序在有问题的对象中注入存储库,并执行业务逻辑,如果您想使用存储库或数据访问的其他实现,上述存储库中的接口是一种很好的去耦方法。

      我本人与LINQ to SQL类有一种爱恨关系,但我想我会扮演devils advocate:-),首先解决您提出的问题:-

      1º我编写了我的业务层GUI, 等后来在桌子上 数据库中的帐户已更改 (示例:更改其中一个的名称) 列),然后我需要重建 “LINQ到SQL类”和我的所有代码 层需要重新编码,因为 我的“帐户”对象已更改

      一般的方法是将行为添加到LINQ to SQL生成的部分类中,当您从数据上下文刷新表时,这些文件不会被替换。如果您更改了列名,并且不想更改其余代码,只需在设计器中更新类以使用旧列名

      例如,即使您将POCOs用于NHibernate的持久化,您仍然需要更改映射,所以我并不认为这是一个问题

      2º如果我需要其他存储库(MySQL、Oracle、XML、其他), 我将使用什么“帐户”类

      就我个人而言,我会在这一点上给YAGNI打电话,如果您真的预期需要对多个数据库的支持,那么LINQ to SQL可能不是最好的解决方案。在任何情况下(只是为了保持您的基础架构在整个应用程序中的一致性),NHibernate之类的工具都会对这种情况提供更好的支持

      继续添加自定义帐户类,映射代码可以由AutoMapper之类的工具来处理,尽管这可能意味着您放弃了延迟加载之类的操作(这对您来说可能不是什么大问题)

      最终,完全控制您的实体(例如,不必使用无参数构造函数、控制安装等、映射到一列或两列的简单用户类型)是非常有利的,如果您觉得您的应用程序可能会从中受益,那么这可能是一条路,但您将在存储库实现中付出代价,这将因为映射代码和处理是否需要更新/删除/插入内容而变得复杂

      一个好的折衷方法可能是简单地对接口(例如IAccount)进行编码,这应该定义您期望从帐户获得的属性和方法。然后,您的存储库将成为

       IAccount GetById(int accountId);
      
      然后,您可以自由决定实现是什么(即,它是由LINQ到SQL类还是由投影/映射实现),如果您将来选择自定义类,则只需将实现移动到该类并更改存储库实现即可

      归根结底,这取决于应用程序,如果您认为它最终将成为一个具有极其复杂的业务逻辑的大型应用程序,那么无论如何,我会选择一个隔离的域层,它至少会尝试忽略持久性。然而,如果不是这样,那么选择存储库模式只是实现良好的可测试性和数据访问之上的简单抽象的一种方法。我不明白为什么显式地将LINQ引用到SQL类并将它们用作简单的域层是如此重要