2010-06-08 102 views
0

我正在使用LINQ和LINQKit在C#中编写应用程序。我有一个非常大的数据库表,里面有公司注册号。使用谓词构建器的LinqKit堆栈溢出异常

我想要做一个LINQ查询,它将产生等效的SQL: select * from table1 where'123','456''in'子句中可能有数千个术语。

首先我从国家等领域获得公司注册号码。

我那么所有的公司注册号码添加到谓词:

 var predicate = PredicateExtensions.False<table2>(); 
     if (RegNos != null) 
     { 
      foreach (int searchTerm in RegNos) 
      { 
       int temp = searchTerm; 
       predicate = predicate.Or(ec => ec.regno.Equals(temp)); 
      } 
     } 

在Windows Vista专业版加4063项条款后堆栈溢出异常发生。在Windows Server 2003上添加了大约1000个术语后发生堆栈溢出异常。我不得不快速解决这个问题的演示。

为了解决我用这个符号的问题:

 var predicate = PredicateExtensions.False<table2>(); 
     if (RegNos != null) 
     { 
      predicate = predicate.Or(ec => RegNos.Contains(ec.regno)); 
     } 

我的问题是:

  1. 为什么一个堆栈溢出发生使用foreach循环?

  2. 我认为Windows Server 2003的每个进程\线程比NT \ 2000 \ XP \ Vista \ Windows 7工作站版本的Windows要小得多。

  3. 哪个是使用LINQ和LINQKit实现这个最快和最正确的方法?

有人建议我停止使用LINQ,回到动态SQL或ADO.NET,但我想使用LINQ和LINQKit是更好的可维护性。

回答

1

这里有几个问题。首先,封面下的L2S使用SQL UDF sp_execsql。 SQL UDF最多可以传递2100个参数,IIRC,常量和比较始终作为参数发送。所以,即使表达式求值器没有死亡,结果查询也不会运行。表达式评估者可能因为PredicateBuilder嵌套添加的表达式而死亡,并且L2S表达式评估者递归地遍历表达式树。也许你可以将大型过滤器列表填入临时表并加入它?我相信设计师支持命名临时表,或者您可以使用表值sproc插入过滤器值,然后使用L2S来完成繁重的工作。