Fixing the "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){
}
}
}
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, 一次性先把数据读出来
var contacts = from c in db.Contact
select c; List results = contacts.ToList(); foreach (Contact c in results){
}
提示:contacts.ToList() 的作用是强制加载contact列表,也就是先强制执行查询,再做后续处理。
使用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
- using System;
- using System.Threading;
- using System.Data.SqlClient;
- using System.Configuration;
- namespace ConsoleApplication1
- {
- public class Example
- {
- public static void Main()
- {
- SqlConnection sql1 = new SqlConnection("server=(local);Integrated Security = true;database=AdventureWorks;");
- sql1.Open();
- SqlCommand comm1 = new SqlCommand();
- comm1.CommandText = "select 1";
- comm1.CommandType = System.Data.CommandType.Text;
- comm1.Connection = sql1;
- comm1.ExecuteNonQuery();
- sql1.Close();
- Console.ReadLine();
- }
- }
- }
编译后,打开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";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SqlCommand cmd1 = new SqlCommand("select * from customers", conn);
SqlCommand cmd2 = new SqlCommand("select * from orders", conn);
SqlDataReader rdr1 = cmd1.ExecuteReader();
// next statement causes an error prior to SQL Server 2005
SqlDataReader rdr2 = cmd2.ExecuteReader();
// 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