我认为我正在进行的Web项目中存在一些设计错误(我正在使用Linq2SQL实现存储库模式) 1)每个存储库都创建自己的DataContext(这是正确的吗?这应该是这样的) 例如:
public class SQLPersonRepository : IPersonRepository
{
DataContext dc;
public SQLPersonRepository(string connectionString)
{
dc = new DataContext(connectionString, Mapping.GetMapping());
personTable = (dc).GetTable<Person>();
personRoleTable = (dc).GetTable<PersonRole>();
roleTable = (dc).GetTable<Role>();
}
Get Method
Add Methods for the different Tables
Save Method
}
和另一个例子:
class SQLTrainingCenterRepository:ITrainingCenterRepository
{
DataContext dc;
private Table<Trainingcenter> trainingCenterTable;
public SQLTrainingCenterRepository(string connectionString)
{
dc = new DataContext(connectionString, Mapping.GetMapping());
trainingCenterTable = (dc).GetTable<Trainingcenter>();
}
Get Methods
Add Method
Save Method
}
你可以弄清楚我正在使用IoC(Windsor,使用lifestyle =“PerWebRequest”)。
2)为每个存储库使用服务层。例如。对于人
public class PersonBusinessLayer
{
IPersonRepository personRepository;
public PersonBusinessLayer(IPersonRepository personRepository)
{
this.personRepository = personRepository;
}
... diverse Get Methods
Add Method (wrapper around repository.Add)
Save Method (wrapper around repository.Save)
}
这是定义服务层的正确方法吗?或者我应该使用一个引用所有存储库的服务类?
3)personTable与trainingCenterTable之间存在关联。每次我在TrainingCenter-Service中插入一些内容时,我还必须在Person-Service中插入一条记录。所以解决这个问题的方法是:
TrainingCenterBusinessLayer.Insert(trainingCenter);
PersonBusinessLayer.Insert(person);
当然我希望这两个插入以Transactional方式发生,所以我决定将这些语句包装在
中using (TransactionScope scope = new TransactionScope())
{
...
}
因此出现了一个新问题:服务器上的MSDTC'。\ SQLEXPRESS'不可用(因为有不同的DataContexts,对吧?)。如何克服这个?!?
解决方案是在外部创建DataContext并将其作为参数传递给存储库!正确的思考?但是如何实施?
4)使用现有设计我必须致电: TrainingCenterBusinessLayer.Save(); PersonBusinessLayer.Save(); 我觉得这是错的! save()操作应该在DataContext中调用一次。但是怎么样? (显然,如果解决上述问题,这可以解决)。
答案 0 :(得分:1)
我遇到了类似的问题。我解决它的方法是将DataContext传递到我的存储库中。然后我使用StructureMap为每个Web请求创建一个DataContext实例。
您可能会发现以下帖子很有趣:
Linq to sql multiple data context in same transaction
http://www.west-wind.com/weblog/posts/246222.aspx
http://blog.codeville.net/2007/11/29/linq-to-sql-the-multi-tier-story/
答案 1 :(得分:0)
如果你正在进行全面的DI,你应该尝试传递一个抽象(接口)作为依赖。这样,如果你想模仿它,你可以轻松地交换它的实现。
DataContext
可以传递,但也许有点沉重。更好的选择IMO将是IDbConnection
。
连接字符串实际上不是依赖项,它是用于初始化依赖项的特定实现的参数。
还有MvcFakes方法与IDataContext
和上下文包装器,但我觉得这很痛苦。只要您的DataContext
实例共享相同的连接实例,您就不需要分布式事务。