【转】Entity Framework中出现"已有打开的与此命令相关联的 DataReader,必须首先将它关闭。"的解决方案

简介: from:http://www.cnblogs.com/china0zzl/archive/2009/08/06/1540025.html        前期搭建一个ASP.NET MVC应用的框架过程中,使用了Entity Framework框架作为数据处理部分。

     from:http://www.cnblogs.com/china0zzl/archive/2009/08/06/1540025.html

 

     前期搭建一个ASP.NET MVC应用的框架过程中,使用了Entity Framework框架作为数据处理部分。其中在Linq to Entity操作过程中偶出现 “已有打开的与此命令相关联的 DataReader,必须首先将它关闭。”该问题,经查善友老大的文章找到一链接,得以解决该问题:http://www.netknowledgenow.com/blogs/onmaterialize/archive/2006/09/20/Fixing-the-_2200_There-is-already-an-open-DataReader-associated-with-this-Command-which-must-be-closed-first_2E002200_-exception-in-Entity-Framework.aspx

      下面摘录该博文内容:

Fixing the "There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework

    Once you get your model, database and mapping metadata files configured correctly for Entity Framework, one of the first exceptions that you're likely to face is the DataReader already open exception. It will normally surface when you're iterating over a result set and then lazy loading a child collection. In the following example I have a Contact entity that has a Phone collection. If I lazy load the Phones then I'll get the DataReader exception.

var contacts = from c in db.Contact
select c;
foreach (Contact c in contacts)
{
    if (c.Phones.IsLoaded == false)
        c.Phones.Load();
    if (c.Phones.Count > 0)
    {
        Console.WriteLine(c.LastName);
        foreach (ContactPhone p in c.Phones)
        {
            Console.WriteLine("\t"+p.ContactPhoneId);
        }
    }
}

    The reason for the exception is that there is an open data reader while reading in the contacts and then the loading of the child Phone collection is attempting to open another DataReader. By default, the SqlClient ADO.NET driver does not allow this.

    There are two ways to fix this. First, if you are using SQL Server 2005, you can just enable MARS in your connection string.

 
 
add name="YourDBConnectionString" connectionString="metadata=.;
	provider=System.Data.SqlClient;provider connection string="Data Source=irv-dev-vms05;Initial Catalog=YourDB;Integrated Security=True;
	MultipleActiveResultSets=true"" providerName="System.Data.Mapping" /

    A second option is to read all the results into memory in one shot and close the connection. Then you are free to open another connection to the database to read in the child entities. So how do you control this? The trip to the database does not happen when the LINQ statement is assigned to the var in the code above. Instead, the query to the database happens during the inplicit call to the enumerator of the contacts collection. To force all the contacts to be loaded, simply copy them to a list in memory using the ToList method and then continue the normal processing.

var contacts = from c in db.Contact
select c;
List results = contacts.ToList();
foreach (Contact c in results)
{
    if (c.Phones.IsLoaded == false)
        c.Phones.Load();
    if (c.Phones.Count > 0)
    {
        Console.WriteLine(c.LastName);
        foreach (ContactPhone p in c.Phones)
        {
            Console.WriteLine("\t"+p.ContactPhoneId);
        }
    }
}

 

    This works as expected. Another important realization here is that there is an open connection to the database as long as you are reading in records through that enumerator! A novice programmer may unwittingly include a massive number of time consuming operations within the foreach loop (calling a web service, for example, comes to mind) which will keep the connection to the database open for an inordinate length of time. Of course, you won't fall into that trap.

 

 

******************************************************

文中提到解决方案有两种:

1、数据库为SQL Server 2005版本时,可以在web.config数据库链接串中加入MultipleActiveResultSets=true。

2、进行重复操作之前,将数据查询结果放入内存中,再进行使用。

具体解释看上文。

 

 

目录
相关文章
|
开发框架 .NET 数据库
.NETCore 获取数据库上下文[实例的方法和配置连接字符串
.NETCore 获取数据库上下文[实例的方法和配置连接字符串
704 1
|
存储 SQL 数据库
Entity Framework Core 捕获数据库变动
Entity Framework Core 捕获数据库变动
155 0
|
数据库
Entity FrameWork初始化数据库的四种策略
程序猿就是苦逼,每天还得分出一些时间去写博文。天真的很热,今天就随便写一点啦! 1、EF初始化数据库的四中策略 EF可以根据项目中的模型自动创建数据库。下面我们就分类看看Entity Framework数据库初始化四种策略 一、 //每次运行都会创建新的数据库       Database.
1468 0
|
Web App开发 数据库 容器
EntityFramework中常用的数据删除方式速度对比
EntityFramework中常用的数据删除方式速度对比http://www.bieryun.com/3375.html 最近在学EF,目前了解到删除操作有三种方式, 第一,官方推荐的先查询数据,再根据查询的对象,删除对象。
1387 0