程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> LINQ參數過多時的解決方案

LINQ參數過多時的解決方案

編輯:關於.NET

在項目中曾有這樣的應用,權限篩選時先組織出員工的id,然後使用LINQ在相應的表中查詢數據,條件是這些查詢出來的數據的id必須在剛才權限篩選出來的id中,但是如果權限中的id太多,就會出現問題“傳入的表格格式數據流(TDS)遠程過程調用(RPC)協議流不正確。此 RPC 請求中提供了過多的參數。最多應為 2100”。我推斷可能是SQLServer中使用參數不能超過2100的原因。以上描述請看下邊的例子。

int[] inputList = new int[2100];
for (int i = 0; i < inputList.Length; i++)
{
inputList[i] = i;
}
DataClasses1DataContext dc = new DataClasses1DataContext();
var t=(from x in dc.test1
select x).Where(c=>inputList.Contains(c.testID));
dc.Log = Console.Out;
foreach (var item in t)
{
Console.WriteLine(item.testID);
}

運行以上代碼會報“傳入的表格格式數據流(TDS)遠程過程調用(RPC)協議流不正確。此 RPC 請求中提供了過多的參數。最多應為 2100”異常,如果將inputList數組大小改為5,執行的sql如下:

SELECT [t0].[testID], [t0].[testContent], [t0].[p]
FROM [dbo].[test1] AS [t0]
WHERE [t0].[testID] IN (@p0, @p1, @p2, @p3, @p4)

現在問題是如果超過2100個參數怎麼辦,我沒想出用linq實現的好辦法,這裡使用了一個折中的辦法

public static List<T> test<T>()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
dc.Log = Console.Out;
int[] inputList = new int[2100];
StringBuilder sqlstr = new StringBuilder("select * from ");
sqlstr.Append(typeof(T).Name);
sqlstr.Append(" where testid in (");
for (int i = 0; i < inputList.Length; i++)
{
sqlstr.Append(i);
if (i < inputList.Length - 1)
{
sqlstr.Append(",");
}
else
{
sqlstr.Append(")");
}
}
SqlCommand cmd = new SqlCommand(sqlstr.ToString(), (SqlConnection)dc.Connection);
dc.Connection.Open();
SqlDataReader dr = cmd.ExecuteReader();
List<T> t = dc.Translate<T>(dr).ToList();
return t;
}
static void Main(string[] args)
{
List<test1> l = MyClass.test<test1>();
foreach (var item in l)
{
Console.WriteLine(item.testID);
}
}

這裡利用了反射得到表名,然後利用Linq中的Translate方法將SqlDataReader轉換成相應的類。

8月11日更新:

如果inputList不是一個數組而是一個IQueryable,直接用就沒什麼問題

var tt = (from x in dc.test
select x.testid);
var t = from x in dc.log
where tt.Contains<int?>(x.logId)
select x;
dc.Log = Console.Out;
foreach (var item in t)
{
Console.WriteLine(item.logMessage);
}

拼接出的sql語句如下:

SELECT [t0].[logId], [t0].[logMessage], [t0].[x]
FROM [dbo].[log] AS [t0]
WHERE EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[test] AS [t1]
WHERE [t1].[testid] = ([t0].[logId])
)
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved