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

时间:2023-11-11 21:48:38

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

下面代码可能会报如标题所示错误

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

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) {
foreach (ContactPhone p in c.Phones){
}
}
}

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

Tip: 真正执行查询是在foreach语句执行时才发生,在之前只是建立查询。

解决办法:

1,修改连接串,加上MultipleActiveResultSets=true

  <connectionStrings>
<add name="connectionStrings" connectionString="Data Source=(local);Initial Catalog=xxx;uid=xx;pwd=xx;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
</connectionStrings>

2, 一次性先把数据读出来

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

var contacts = from c in db.Contact
select c; List results = contacts.ToList(); foreach (Contact c in results){
}

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

提示:contacts.ToList() 的作用是强制加载contact列表,也就是先强制执行查询,再做后续处理。

原文:http://netknowledge.net/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

关于 MultipleActiveResultSets

使用MultipleActiveResultSets复用Sql Server 2008数据库连接

分类: Sql Server 20082009-05-19 23:18 3225人阅读 评论(1) 收藏 举报

数据库sql serversecurityserversqlclass

MultipleActiveResultSets可以使数据库连接复用。这样就不怕数据库的连接资源被耗尽了。使用方法很简单,只需要把它加到数据的连接字符串中即可。

例如:server=(local);Integrated Security = true;database=AdventureWorks;MultipleActiveResultSets=true;

测试用例:

[c-sharp] view plaincopy

  1. using System; 
  2. using System.Threading; 
  3. using System.Data.SqlClient; 
  4. using System.Configuration; 
  5. namespace ConsoleApplication1 
  6. public class Example 
  7. public static void Main() 
  8. SqlConnection sql1 = new SqlConnection("server=(local);Integrated Security = true;database=AdventureWorks;"); 
  9. sql1.Open(); 
  10. SqlCommand comm1 = new SqlCommand(); 
  11. comm1.CommandText = "select 1"; 
  12. comm1.CommandType = System.Data.CommandType.Text; 
  13. comm1.Connection = sql1; 
  14. comm1.ExecuteNonQuery(); 
  15. sql1.Close(); 
  16. Console.ReadLine(); 
  17. }

编译后,打开bin/debug/ConsoleApplication1.exe。

在SQL Server 2008 Management Studio中打开一个新窗口,输入sp_who

按F5执行,可以发现已经有一个用户连接到AdventureWorks数据库了。

再打开一个ConsoleApplication1.exe,发现又会多一个用户连接到AdventureWorks数据库。

现在把程序的连接字符串改为server=(local);Integrated Security = true;database=AdventureWorks;MultipleActiveResultSets=true;

按上面的顺序执行,发现不管打开多少个ConsoleApplication1.exe,数据库中没有用户或只有一个用户连接着AdventureWorks数据库。

这就是数据库连接复用的好处了。

关于数据库连接字符串的其它用法,参见:

http://blog.csdn.net/tjvictor/archive/2009/03/19/4004277.aspx

MultipleActiveResultSets

ADO.NET 1.x 利用SqlDataReader读取数据,针对每个结果集需要一个独立的连接。当然,你还必须管理这些连接并且要付出相应的内存和潜在的应用程序中的高度拥挤的瓶颈代价-特别是在数据集中的Web应用程序中。

ADO.NET 2.的一个新特征多数据结果集(Multiple Active Result Sets,简称MARS)-它允许在单个连接上执行多重的数据库查询或存储过程。这样的结果是,你能够在单个连接上得到和管理多个、仅向前引用的、只读的结果集。目前实现这个功能的数据库只有Sql Server 2005。所以当我们针对Sql Sever 2005的时候,需要重新审视DataReader对象的使用。使用SqlServer 2005,可以在一个Command对象上同时打开多个DataReader,节约数据库联接所耗费的服务器资源,在实际开发中普遍存在的一种典型的从数据库中读写数据的情形是,你可以使用多重连接而现在只用一个连接就足够了。例如,如果你有一些来自于几个表中的数据-它们不能被联结到一个查询中,那么你就会有多重的连接-每个连接都有一个与之相关连的命令用于读取数据。同样,如果你正在向一个表写数据,那么你需要另外一个连接或连接集合-如果有多个表要被更新的话。

例如下面的代码

//MultipleActiveResultSets=true打开联接

string connstr = "server=(local);database=northwind;integrated security=true;MultipleActiveResultSets=true"; There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework

SqlConnection conn = new SqlConnection(connstr);
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework            conn.Open();
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework            SqlCommand cmd1 = new SqlCommand("select * from customers", conn);
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework            SqlCommand cmd2 = new SqlCommand("select * from orders", conn);
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework            SqlDataReader rdr1 = cmd1.ExecuteReader();
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework           // next statement causes an error prior to SQL Server 2005
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework            SqlDataReader rdr2 = cmd2.ExecuteReader();
There is already an open DataReader associated with this Command which must be closed first." exception in Entity Framework           // now you can reader from rdr1 and rdr2 at the same time.

conn.Close();

http://www.cnblogs.com/RobotH/archive/2007/08/22/865942.html

http://www.cnblogs.com/season2009/archive/2012/12/25/2831863.html

http://blog.csdn.net/tjvictor/article/details/4202535