"已经有一个与此命令关联的开放式数据加载器" - 即使使用Include()

Moh*_*een 2 linq asp.net-mvc-4 entity-framework-5

我正在尝试加载所有Dish对象.Dish并且DishImages具有一对多的关系,即a Dish可以有许多DishImage与之关联的s.

这是两个类的代码.

  1. DishImage

这是我试图在动作方法中检索它的方式:

    [ChildActionOnly]
    public PartialViewResult TopDishes()
    {
        IEnumerable<Dish> topDishes = dishRepository.Dishes.Include( d => d.DishImages );                                                        
        return PartialView(topDishes);
    }
Run Code Online (Sandbox Code Playgroud)

以下是查看代码:

  @model IEnumerable<RestaurantHub.Domain.Entities.Dish>

 @foreach (var dish in Model)
 {
    <div class="top-ten-offers-list">

      <div class="top-ten-offer">
        <p class="top-ten-deal-description">
            @dish.Description
        </p>

        <img src="@dish.DishImages.First().ImagePath" />
        <p class="top-ten-deal-title">@dish.Name</p>
     </div>

   </div>
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了他们大多数建议使用的几个SO问题Include()(我正在做),其他人建议将MARS设置为true.我相信我在这里错过了一些微妙的观点.任何帮助表示赞赏.

调试信息:

如果我将代码调试到action方法,我可以验证(通过枚举结果)正在加载正确的数据.但是当控件foreach在视图中到达循环时,它会抛出上述错误.

如果我@dish.DishImages.First().ImagePath从视图中删除该行,它工作正常,但我没有得到任何图像.

结果集的调试视图

Ami*_*aqi 6

那是因为你同时有多个查询:

...... 当Code First按惯例创建连接时,它已经在我们的示例中,它将启用MARS.如果您提供自己的连接,则需要确保如果您希望能够有多个活动查询,则启用MARS.

如果您未启用MARS并且您的代码尝试运行两个活动查询,则会收到异常.您收到的异常将取决于触发第二个查询的操作,但内部异常将是一个InvalidOperationException,指出"已经有一个与此命令关联的打开的DataReader必须先关闭." -from Julia Lerman's Programming EF DbContext

您似乎已在web.config中创建了自己的EF连接.如果是这样,您应该添加MultipleActiveResultSets=True;到其connectionString属性:

<add name="..." connectionString="metadata=res:...;provider=System.Data.SqlClient;provider connection string=&quot;data source=... ;
MultipleActiveResultSets=True; //Add this
App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
Run Code Online (Sandbox Code Playgroud)

更新:

事实上,问题来自您的观点.该<img src="@dish.DishImages.First().ImagePath" />行导致该异常.你问为什么?!我会告诉你原因:

首先,您对数据库执行了一个查询:

IEnumerable<Dish> topDishes = dishRepository.Dishes.Include( d => d.DishImages );                                                        
return PartialView(topDishes);
Run Code Online (Sandbox Code Playgroud)

但是,事实上你没有执行任何查询!您刚刚创建IEnumerable集合(那是因为你没打电话.ToList(),.AsEnumerable()等),这是没有问题的.

所以你将一个集合传递给你的视图.第一个查询在你的foreach循环中执行- 好的,仍然没有问题......

直到我们到达img标签:<img src="@dish.DishImages.First().ImagePath" />.This(@dish.DishImages.First())对db执行新查询 - >问题!

解:

我不知道.ToList()在你的控制器中打电话来解决你的问题 - 也许吧.但是,您当前的EF连接字符串必须具有MultipleActiveResultSets=True;在这些情况下正常工作的属性.