正确使用'使用'实体框架中的陈述

时间:2017-01-05 09:30:20

标签: c# entity-framework linq using

我对使用using语句有一些疑问。我理解它的作用(如果我是正确的,它会处理所有打开的连接等),但我不确定我应该如何正确使用它。

我工作的项目并不包含任何您不需要实体框架的存储库。

所以基本上,我在我的方法中获得Guids列表作为参数。这些ID适用于餐馆,我想检索这些餐馆的所有评论。

目前,我正在检索列表,如下所示:

public void DoSomething(List<Guid> restaurantIds)
{
    List<Review> reviews;
    using (var db = new Context())
    {
        reviews = db.Reviews.Where(x => restaurantIds.Contains(x.RestaurantId)).ToList();
    }
    //More stuff here
}

在using语句之外声明列表这是一种常见的不良做法吗?我想到了一些替代方案,但我(再次)不确定什么会更好。

  1. 在同一个类中创建一个单独的方法,然后返回列表。这种方式在我的DoSomething方法中,我可以像这样使用它:List<Review> reviews = GetReviewsFromRestaurants(restaurantIds);
  2. 我必须首先创建上下文,然后使用没有using块的LINQ语句。我不得不在完成.Dispose()之后致电。
  3. 在我的示例中使用using语句时是否存在问题?如果是这样,替代方案会更好吗?如果情况并非如此,你能举例说明我应该如何检索这个清单吗?

3 个答案:

答案 0 :(得分:3)

在这种情况下,大括号定义了自己的范围。您将在大括号范围之外声明的变量将在大括号内可见,并且可以。

它实际上是try catch块的简写。

List<Review> reviews;
var db = new Context();
try
{
   reviews = db.Reviews.Where(x => restaurantIds.Contains(x.RestaurantId)).ToList();
}
finally
{
  db.Dispose();
} 

你的代码片段比这简洁得多。编译器将始终在&#34;使用&#34;上调用.Dispose。对象

答案 1 :(得分:2)

关于https变量,我不认为你在reviews块之外声明它是不好的。

<强> 1。建议使用单独的方法。实际上,您仍然可以使用将处理所有这些基本操作的存储库类(using),例如:基于单个或多个标识符获取所有餐馆,创建新餐馆,更改餐馆的一些数据。

这可确保您将业务逻辑与基本操作分开。

<强> 2。一次性上下文与显式Dispose()。一次性上下文显然更好,因为它确保即使您的代码失败也会调用Dispose()。

更大的图片 - 实体框架和上下文配置

已经讨论过here。此外,this article表明配置并不像看起来那么必要。

就个人而言,我一直是工作单元模式,允许多次更改(在各种存储库/实体上),并且没有因为不处理上下文而遇到麻烦。

答案 2 :(得分:0)

对于“什么是不良做法”通常没有万能的答案,你的问题也不例外。虽然通常显然是 prectices,有时显然是良好的做法,但有很多因素会影响您的决定(例如您的要求,组织规则或团队经验)。< / p>

你可以在实体框架中保留一个上下文的时间超过一会儿(虽然保持它开放非常长也可能不是一个好主意),只要你确定你处理它在末尾。但是,将using应用于您的上下文也没有错。在Web应用程序中,上下文通常使用的时间非常短,而低级别的连接池通常会使解决方案保持高效。