线程和linq数据上下文
本文关键字:上下文 数据 linq 线程 | 更新日期: 2023-09-27 18:15:04
这是我的代码:
DatabaseDataContext context = new DatabaseDataContext();
var sourceList = (from q in context.Table1 where col1< 2000 select q).ToList();
foreach( Type x in sourceList)
{
var task = Task.Factory.StartNew(() => FetchData(x));
}
FetchData(x)
{
SomeBO obj = new SomeBO();
obj.Prop1 = x.Table2.col;
obj.Prop2 = x.Table3.col;
}
当我执行这段代码时,我得到一个异常'已经有一个打开的数据阅读器与这个命令相关联,必须先关闭'。我怎么能使方法'FetchData'并行执行的所有列表项目在'sourceList'?
您正在多个线程中使用一个上下文实例。但是上下文不是线程安全的。打开MARS也无济于事,任务将继续争夺连接。
解决方案是为每个任务创建一个新上下文。比如FetchData(x)
{
SomeBO obj = new SomeBO();
using(var context = new DatabaseDataContext())
{
obj.Prop1 = context.Table2s.Where(t2 => t2.Id == x.Id)
.FirstOrDefault().col;
...
}
}
但是我不得不猜测,因为我不知道你的类的结构
您需要正确地在connectionstring中包含MARS。
这样的:
var sqlBuilder = new SqlConnectionStringBuilder
{
DataSource = "myServer",
InitialCatalog = "mydatabase",
IntegratedSecurity = false,
UserID = "user",
Password = "pass",
MultipleActiveResultSets = true //<-- here
};
和
var efConnString = new EntityConnectionStringBuilder
{
ProviderConnectionString = sqlBuilder.ToString()
//other properties omitted
}
或者你可以用传统的方式:
string connectionString = "Data Source=MSSQL1;" +
"Initial Catalog=AdventureWorks;Integrated Security=SSPI" +
"MultipleActiveResultSets=True";
'已经有一个与此命令相关联的打开的数据读取器,必须先关闭'
你可以看一下链接实体框架-已经有一个与此命令相关的开放数据读取器
我怎么能使方法'FetchData'并行执行的所有列表项目在'sourceList'?
我认为你想要Parallel。ForEach