我在 VS2008 中使用实体框架。我正在使用 esql 访问数据库中的对象以获取 WHERE IN 功能。我将大量 ID 传递给 select 语句,因此我将其分成 800 个组。然后我将每个块的结果合并在一起。我的目标是并行获取每个块的结果,而不是同步等待。我安装了 Reactive Framework,并且很确定我需要使用 ForkJoin。但是,我不知道如何转换这个函数来使用它。这是我现有的代码:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var retList = new List<TElement>();
foreach (var idChunk in chunkedIds)
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
retList.AddRange(query);
}
return retList;
}
谢谢!
编辑>>>我修改了代码以使用Poor Man,如下所示:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var chunkLists = new List<IEnumerable<TElement>>();
Parallel.ForEach(chunkedIds, idChunk =>
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
var retList = new List<TElement>();
foreach (var chunkList in chunkLists)
{
retList.AddRange(chunkList);
}
return retList;
}
第一次效果很好。但是我第二次运行它时,我得到了这个错误:
连接未关闭。连接的当前状态是正在连接。说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。
异常详细信息:System.InvalidOperationException:连接未关闭。连接的当前状态是正在连接。
源错误:
第 49 行:foreach (var iAsyncResult in resultList) 第 50 行:{ 第 51 行:del.EndInvoke(iAsyncResult); 第 52 行:iAsyncResult.AsyncWaitHandle.Close(); 第 53 行:}
有趣的是,b/c Emre(该库的作者)对他的原始帖子进行了编辑,讨论了他如何添加这些代码行以增加安全性。我用对了吗?还是他的 v1 更安全?