3

我在存储库的每种方法中都使用了块。如果我想交叉引用方法,初始化另一个 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 

   } 
}
4

4 回答 4

4

实际上,我认为在您的存储库中创建和处置数据上下文是语义上的(或者我应该怎么说),这是不正确的。

我的意思是:如果您在存储库的每种方法中打开与数据库的新连接,恕我直言,您做错了。这太细了。存储库类不知道使用它的“上下文”。您的存储库不应负责打开/关闭连接或启动和提交事务。上下文为王,存储库不知道使用它的上下文。因此,恕我直言,应用层或服务层有责任打开新的 DataContext 对象,并关闭/处置它们。(同样适用于交易)。

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

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();

}

(这不是真实世界的代码;而且它甚至不会编译,因为 ISession 没有 Commit 方法。;)相反,StartTransaction 返回一个具有某种提交方法的 ITransaction,但我想你会抓住我的漂移。;) )

于 2009-01-17T11:53:58.030 回答
3

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

于 2009-01-15T23:50:09.293 回答
3

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

请注意,您通常不需要处理数据上下文,尽管我倾向于处理任何实现 IDisposable 的东西。

于 2009-01-15T23:53:38.613 回答
2

你可以在一个类上调用 .Dispose() 而不使用“using”语句——通常你会在你的存储库的 Dispose 方法中执行此操作,如果你有的话。

于 2009-01-15T23:45:30.283 回答