0

我认为我正在进行的 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);

当然我希望这两个插入以事务方式发生,所以我决定将这些语句包装在

using (TransactionScope scope = new TransactionScope())
{
...
}

所以出现了一个新问题:服务器'.\SQLEXPRESS'上的MSDTC不可用(因为有不同的DataContexts,对吗??)。如何克服这个?!?

一种解决方案是在外部创建 DataContext 并将其作为参数传递给存储库!??正确的想法?但如何实施?

4)使用现有设计,我必须调用:TrainingCenterBusinessLayer.Save(); PersonBusinessLayer.Save(); 我认为这是错误的!save() 操作应在 DataContext 中调用一次。但是怎么做?(显然,如果解决了上述问题,这可以解决)。

4

2 回答 2

1

我和你自己也有类似的问题。我解决它的方法是将 DataContext 传递到我的存储库中。然后,我使用 StructureMap 为每个 Web 请求创建一个 DataContext 实例。

您可能会发现以下帖子很有趣:

Linq to sql 同一事务中的多个数据上下文

http://www.west-wind.com/weblog/posts/246222.aspx

http://blog.codeville.net/2007/11/29/linq-to-sql-the-multi-tier-story/

于 2010-01-06T03:37:56.870 回答
0

如果您正在做全面的 DI,您应该尝试将抽象(接口)作为依赖项传递。这样,如果你想模拟它,你可以轻松地换掉它的实现。

DataContext可以四处走走,但可能有点重。IMO 是一个更好的选择IDbConnection

连接字符串并不是真正的依赖项,它是用于初始化依赖项的特定实现的参数。

还有带有上下文包装器的MvcFakes方法IDataContext,但我发现这很痛苦。只要您的DataContext实例共享相同的连接实例,您就不需要分布式事务。

于 2010-01-06T04:04:37.563 回答