C#MVC库继承和共同的DataContext

问题描述:

说我有一个GenericRepository:C#MVC库继承和共同的DataContext

public class IGenericRepository 
{ 
    // bla bla bla 
} 

public class GenericRepository : IGenericRepository 
{ 
    public myDataContext dc = new myDataContext(); 

    // bla bla bla 
} 

和我有类特定的资源库:

public class CategoryRepository : GenericRepository 
{ 
    // bla bla bla 
} 

,并在我的控制器:

public ActionResult something() 
{ 
    CategoryRepository cr = new CategoryRepository(); 
    GenericRepository gr = new GenericRepository(); 
    Category cat = cr.GetMostUsedCategory(); 
    SubCategory sub = gr.GetById(15); 

    // And after I make some changes on these two entities I have to: 

    cr.Save(); 
    gr.Save(); 
} 

现在,是否可以使用适用于所有存储库的通用数据环境?所以,当我从gr.Save()保存它将申请cr?我的意思是:

//Instead of 
cr.Save(); 
gr.Save(); 

//I want 
gr.Save(); // And my category will also be saved. 

这可能吗?

你能做这样的事吗? (将您的派生存储库传递给泛型)

public class IGenericRepository 
{ 
    void Save(); 
} 

public class GenericRepository : IGenericRepository 
{  
    public myDataContext dc = new myDataContext(); 
    private _IGenericRepository = null; 

    // bla bla bla 

    public GenericRepository(IGenericRepository repository) 
    { 
     _IGenericRepository = repository; 
    } 

    void Save() 
    { 
     _IGenericRepository.Save(); 
    }   
} 

IGenericRepository包含您的保存方法吗?

public class IGenericRepository 
{ 
    save{}; 
} 

在你的情况在这里假定CategoryRepository从GenericRepository继承为什么不使用两个电话和therfore相同的上下文中CategoryRepository。然而,最好的方法是通过DI容器注入上下文,并使用容器的LifetimeManager来确保整个HttpRequest具有相同的上下文。

如果你碰巧使用微软的团结,我写了一篇博客文章对此here

+0

好吧,你是对的,对于这个例子我可以做到这一点,但有些情况下我必须使用不同的特定存储库,那么我应该在那里做什么? – Shaokan

+0

如果将相同的上下文注入到两个存储库中,则调用Save将导致期望的行为。然而,通过通过接口抽象上下文,这种模式(工作单元)变得更加明确。然后,您的控制器也将依赖此接口并决定何时调用Save。由于此接口解析为传递到两个存储库的上下文,因此您将获得所需的行为。 –

可以使用Unit Of work模式为这些目的。在你的仓库

//It is the generic datacontext 
public interface IDataContext 
{ 
    void Save(); 
} 

//It is an implementation of the datacontext. You will 
//have one of this class per datacontext 
public class MyDataContext:IDataContext 
{ 
    private DataContext _datacontext; 
    public MyDataContext(DataContext dataContext) 
    { 
     _datacontext = dataContext; 
    } 

    public void Save() 
    { 
     _datacontext.Save(); 
    } 
} 

然后:

您应该添加一个抽象层以上的DataContext的概念

public class GenericRepository<TDataContext> : IGenericRepository where TDataContext: IDataContext,new() 
{ 
    public TDataContext dc = new TDataContext(); 

    // bla bla bla 
} 

public class CategoryRepository:GenericRepository<MyDataContext> 
{ 
    // bla bla bla 
    public void SaveSomething() 
    { 
     dc.Save(); 
    } 
} 

当然,这只是一段路要走:-)你可以改进它,但重点是抽象Datacontext的概念。您可以将您的代码用于任何数据上下文(即使是NHibernate)。