Asp.net mvc 将使用块放入存储库有什么错?

Asp.net mvc 将使用块放入存储库有什么错?,asp.net-mvc,linq,repository-pattern,datacontext,Asp.net Mvc,Linq,Repository Pattern,Datacontext,我的存储库的每个方法中都有使用块。如果我想交叉引用方法,那么初始化另一个Datacontext似乎有违最佳实践我做错了什么?如果我在类中声明Datacontext而不是在方法中使用块,我不会失去处理的能力吗 public IList<something> GetSomething() { using (DB db=new DB()) { ...GetListofSomethingElse(id) } } public IList<somethinge

我的存储库的每个方法中都有使用块。如果我想交叉引用方法,那么初始化另一个Datacontext似乎有违最佳实践我做错了什么?如果我在类中声明Datacontext而不是在方法中使用块,我不会失去处理的能力吗

public IList<something> GetSomething()
{ 
   using (DB db=new DB())

   { ...GetListofSomethingElse(id)

   } 
}

public IList<somethingelse> GetListofSomethingElse(int id)
{ 
    using (DB db=new DB())
   {
     ... return IList 

   } 
}
public IList GetSomething()
{ 
使用(DB=new DB())
{…GetListofSomethingElse(id)
} 
}
公共IList GetListofSomethingElse(int id)
{ 
使用(DB=new DB())
{
…返回IList
} 
}

您可以在类上调用.Dispose(),而无需使用“using”语句-通常,您可以在存储库的Dispose方法中执行此操作(如果您有)。

using语句是语法糖。它使用finally部分中的Dispose()调用编译为try/finally块。它确保即使发生异常也会调用Dispose。

如果不使用using语句,仍然可以显式地进行Dispose。即使不处理数据上下文,交叉引用这些方法仍然会创建新的数据上下文。这可能是好事,也可能不是好事,这取决于你的使用情况。考虑数据上下文的状态管理方面,以及是否要将这些方法彼此隔离。如果要避免一直创建新上下文,请使用将上下文作为参数的版本重载方法


请注意,尽管我倾向于处理任何实现IDisposable的东西。

实际上,我认为在存储库中创建和处理datacontext在语义上(或者我应该怎么说)是不正确的

我的意思是:如果您在存储库的每个方法中打开一个到DB的新连接,那么您就做错了。这太细粒度了。 repository类不知道使用它的“上下文”。您的存储库不应负责打开/关闭连接或启动和提交事务。 上下文是王者,而存储库不知道使用它的上下文。因此,应用层或服务层负责打开新的DataContext对象,并关闭/处理它们。(这同样适用于交易)

所以,我就是这样做的:(注意,我没有使用实体框架,但我使用了NHibernate。我假设EF中的DataContext类与NHibernate中的ISession类似):


(这当然不是真实世界的代码;它甚至不会编译,因为ISession没有提交方法。;)相反,StartTransaction返回一个ITTransaction,它有某种提交方法,但我想你会明白我的意思。;)

有趣的是,我更喜欢这种方式,但这是否违反了数据层和业务层的分离?这是什么意思?ISession/DataContext是一个基础架构问题。基础设施可以在所有层中使用。此外,存储库是“域”中的一级citizin。我的存储库知道它必须使用实现某些接口的“UnitOfWork”对象。如果在数据进入时我从存储库对象向自定义对象赋值,该怎么办?现在,自定义对象被分配到存储库中。按照这里的方式,为了赋值,我必须再次遍历结果。?
using( ISession s = theSessionFactory.OpenSession() )
{
    ICustomerRepository cr = RepositoryFactory.GetCustomerRepository(s);

    Customer c1 = cr.GetCustomer(1);
    Customer c2 = cr.GetCustomer(2);

    // do some other stuff
    s.StartTransaction();

    cr.Save (c1);
    cr.Save (c2);

    s.Commit();

}