傳入的表格格式數據流(TDS)遠程過程調用(RPC)協議流不正確。此 RPC 請求中提供了過多的參數。最多應為 2100


出現這個問題的背景是,判斷一批激活碼在系統中是否已經存在,很傻的一個作法是,把這一批激活碼,以in(in ('ddd','aaa'))的形式來處理,導致問題的出現。

后來,查找資料,http://bbs.csdn.net/topics/350137806

在這里討論的結果是:

 

你的問題不是你不會使用LINQ中的in語句,而是你傳遞給in語句的參數太多了。
長度可能超過2100個,甚至上萬。這多恐怖呀?要知道這些內容最后就會包含在所生成的SQL語句中。
這參數也確實太長太長了。
傳入的表格格式數據流(TDS)遠程過程調用(RPC)協議流不正確。
從這個異常信息就可以知道這不是LINQ的問題。
解決辦法很簡單,只要將調用數據源的AsEnumerable()運算符就可以了。如下面的代碼:

 
NorthwindDataContext db = new NorthwindDataContext(@"C:\LINQ\Northwind.mdf");
 
string[] CustomerIDs = { "ALFKI", "ANATR", "ANTON" };
 
var PartialCustomers =
    from CustomerObject in db.Customers.AsEnumerable()
    where CustomerIDs.Contains(CustomerObject.CustomerID)
    select CustomerObject;
 
foreach (var CustomerObject in PartialCustomers)
{
    Console.WriteLine(CustomerObject.CustomerID);
}
View Code


上面的代碼指定的數據源是db.Customers.AsEnumerable()。

 

從上面的討論結果,可以得到,使用AsEnumerable()延遲加載會使問題得到解決。

那我現在的做法是:從數據庫里,把所有的激活碼都查出來,保存在一個List<String>里面,兩個list進行比較,看是否有重復的存在。

另外,要擴展一個知識:LINQ語句中的.AsEnumerable() 和 .AsQueryable()的區別     參考:http://www.cnblogs.com/jianglan/archive/2011/08/11/2135023.html

在寫LINQ語句的時候,往往會看到.AsEnumerable() 和 .AsQueryable() 。
例如:

string strcon = "Data Source=.\\SQLEXPRESS;Initial Catalog=Db_Example;Persist Security Info=True;User ID=sa;Password=sa";
SqlConnection con = new SqlConnection(strcon);
con.Open();
string strsql = "select * from SC,Course where SC.Cno=Course.Cno";
SqlDataAdapter da = new SqlDataAdapter(strsql,con);
DataSet ds = new DataSet();
da.Fill(ds, "mytable");
DataTable tables=ds.Tables["mytable"]; //創建表
var dslp = from d in tables.AsEnumerable() select d;//執行LINQ語句,這里的.AsEnumerable()是延遲發生,不會立即執行,實際上什么都沒有發生
foreach(var res in dslp)                
{
     Response.Write(res.Field<string>("Cname").ToString());
}

上述代碼使用LINQ 針對數據集中的數據進行篩選和整理,同樣能夠以一種面向對象的思想進行數據集中數據的篩選。在使用LINQ 進行數據集操作時,LINQ 不能直接從數據集對象中查詢,因為數據集對象不支持LINQ 查詢,所以需要使用AsEnumerable 方法返回一個泛型的對象以支持LINQ 的查詢操作。

.AsEnumerable()是延遲執行的,實際上什么都沒有發生,當真正使用對象的時候(例如調用:First, Single, ToList....的時候)才執行。
下面就是.AsEnumerable()與相對應的.AsQueryable()的區別:
AsEnumerable將一個序列向上轉換為一個IEnumerable, 強制將Enumerable類下面的查詢操作符綁定到后續的子查詢當中。
AsQueryable將一個序列向下轉換為一個IQueryable, 它生成了一個本地查詢的IQueryable包裝。

    • .AsEnumerable()延遲執行,不會立即執行。當你調用.AsEnumerable()的時候,實際上什么都沒有發生。
    • .ToList()立即執行
    • 當你需要操作結果的時候,用.ToList(),否則,如果僅僅是用來查詢不需要進一步使用結果集,並可以延遲執行,就用.AsEnumerable()/IEnumerable /IQueryable
    • .AsEnumerable() 雖然延遲執行,但還是訪問數據庫,而.ToList()直接取得結果放在內存中。比如我們需要顯示兩個部門的員工時,部門可以先取出放置在List中,然 后再依次取出各個部門的員工,這時訪問的效率要高一些,因為不需要每次都訪問數據庫去取出部門。
    • IQueryable實現了IEnumberable接口。但IEnumerable<T> 換成IQueryable<T>后速度提高很多。原因:
    • IQueryable 接口與IEnumberable接口的區別:  IEnumerable<T> 泛型類在調用自己的SKip 和 Take 等擴展方法之前數據就已經加載在本地內存里了,而IQueryable<T> 是將Skip ,take 這些方法表達式翻譯成T-SQL語句之后再向SQL服務器發送命令,它並不是把所有數據都加載到內存里來才進行條件過濾。
    • IEnumerable跑的是Linq to Object,強制從數據庫中讀取所有數據到內存先。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM