我正在阅读“ASP.NET 3.5社交网络 - Andrew Siemer”一书,当他使用存储库访问数据时我感到困惑。
以下是他的代码的想法:
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.....
}
}
“Account”类是在“LINQ to SQL Classes”上自动生成的类。
我看到的一些问题:
1º 我编写了我的业务层,GUI等...以后及时更改数据库中的表帐户(例如:更改一列的名称),然后我需要重建“LINQ to SQL Classes”和我所有的我需要重新编码代码层,因为我的“帐户”对象已更改。
2º 如果我需要其他存储库(MySQL,Oracle,XML,其他),我将使用什么“帐户”类?
怎么做?
答案 0 :(得分:2)
本能很好..
我的建议是抽象出LinqToSQL对象,并创建一组业务域对象。然后,Repository可以查询所需的数据并将它们映射到应用程序使用的Domain对象,然后返回这些数据。现在,您的数据访问层与您的应用程序分离,现在您可以完成列出的所有事情。
映射可能很痛苦,因此请查看Automapper之类的工具来实现此目的。
答案 1 :(得分:1)
我自己与LINQ to SQL课程有一种爱恨交织关系,但我认为我会扮演恶魔倡导者:-),首先解决你所提出的观点: -
1º我编写业务层,GUI, 等等......以及后来的表格 数据库中的帐户已更改 (例如:更改一个名称 列),然后我需要重建 “LINQ to SQL Classes”和我的所有代码 层需要重新编码,因为 我的“帐户”对象已更改。
一般方法是您将行为添加到LINQ to SQL生成的分部类中,当您从数据上下文刷新表时,这些文件将不会被替换。如果您更改列的名称而不想更改其余代码,只需更新设计器中的类以使用旧列名称?
即使您使用POCO进行NHibernate持久化,您仍然需要更改映射,所以我并不认为这是一个问题。
2º如果我需要其他存储库(MySQL,Oracle,XML,其他), 我将使用什么“帐户”课程?
就我个人而言,如果您真的希望需要支持多个数据库,我个人就会打电话给YAGNI LINQ to SQL在任何情况下都可能不是最好的解决方案(只是为了让您的基础架构在整个应用程序中保持一致),工具就像NHibernate会对这种情况有更好的支持。
继续添加自定义帐户类,映射代码可以通过AutoMapper等工具来处理,但这可能意味着您放弃了延迟加载(这对您来说可能是也可能不是很重要)等事情。 / p>
最后,它可以非常强大,可以完全控制你的实体(例如,不必使用无参数构造函数,控制实例等,映射到一列或两列的简单用户类型),如果你觉得你的应用程序可能会从中受益,这可能是要走的路,但是你将在存储库实现中付出代价,这将通过映射代码和处理事物是否需要更新/删除/插入而变得复杂。
一个好的中间地带可能只是简单地编码到一个接口(例如IAccount),这应该定义你期望从一个帐户的属性和方法。然后您的存储库将变为
IAccount GetById(int accountId);
然后你可以自由地实现实现(即它是由LINQ to SQL类还是投影/映射实现),如果你将来选择自定义类,那么它就是一个简单的例子将实现移动到该类并更改存储库实现。
最后,它归结为应用程序,如果你认为它将以一种极其复杂的业务逻辑结束一个巨大的应用程序,我会选择一个至少试图持久性无知的隔离域层。但是,如果不是,那么选择存储库模式只是实现良好可测试性的一种方法,并且是一种在数据访问之上的简单抽象。我不明白为什么显式引用LINQ to SQL类并将它们用作简单的域层是如此重要。
答案 2 :(得分:0)
我个人使用NHibernate和FluentNHibernate的组合,并将我的域(业务对象)与其他所有东西分开。我使用来自我的其他层的消息,比如GUI,到我的域,它有一个处理程序,它注入内部的存储库,用于保存有问题的对象并执行业务逻辑,上面的存储库中的接口是一种很好的解耦方法如果您想使用存储库或数据访问的其他实现。