2011-01-26 119 views
1

我想使用LinqToSQL生成一個可能包含很多項目的IN子句。我原來的代碼是這樣的:LinqToSQL在條款

context.Employees.Where(p => EmployeeIDs.Contains(p.EmployeeID)); 

從而結束了每個員工的ID作爲SQL參數生成的條款。問題是如果您超過2100個參數,則會引發異常。我已經在我的應用程序的其他地方通過執行多個查詢併合並結果來解決這個問題。這在簡單的情況下可以正常工作,但我現在正在做一些更復雜的事情,我認爲這不是最好的解決方案。

無論如何,包含產生類似

EmployeesID IN (@p0, @p1, @p2) 

但是,有沒有辦法說服它這樣做?

EmployeesID IN (23, 582, 3948) 

我開始下滑使用動態查詢示例的路徑,但後來意識到,這似乎是隻寫動態LINQ代碼,而不是動態SQL。然後我發現了ExecuteQuery,但我不想手動構建我的整個查詢字符串,只是我想要查詢的特定部分。

更具體地講,我想是這樣的:

context.Employees 
    .Where(p => p.Active == true) 
    .Where("EmployeeID IN (23, 582, 3948)"); 

或者preferrably(這是否會產生中不使用參數):

context.Employees 
    .Where(p => p.Active == true) 
    .Where(p => p.In("EmployeeID", EmployeeIDs)); 

沒有辦法做到這一點?謝謝。

回答

0

您是否可以定義一個查詢來返回基於其他查詢所需的員工ID?使用EXISTS子句檢查employeeIds子查詢的SQL相當於

var employeeIds = from x in context.EitherEmployeesOrSomeOtherRecords 
    where x.SomeConditionIsTrue 
    select x.EmployeeID; //not yet evaluated; employeeIds is an IQueryable 

var employees = from e in context.Employees 
    where employeeIds.Contains(x.EmployeeID) 
    select e; 

這LINQ查詢將LINQ2SQL被消化成單個的SQL語句:如果是這樣,你可以使用嵌套查詢定義搜索。

就強迫Linq2SQL從代碼指定值爲文字,我不認爲你可以,但我可能是錯的。

編輯:好了,那麼,如果你讓邏輯確定如何構建查詢更智能?如果用戶選擇

var employees = from e in context.Employees 
    where TheSameConditionThatCausedItToBeInTheList == true 
    select e; 

:喜歡,如果你有一個「全選」按鈕或複選框,你可以用它來製作一個簡單的查詢,「拉起,將已選定列表中的所有員工」所有然後取消選擇幾下,就可以檢測到(多不選中),而不是拉起「EXCEPT X,Y和Z全體員工」:

var notChecked = uiList.Items.Except(uiList.SelectedItems).Select(x=>x.EmployeeID) 

var employees = from e in context.Employees 
    where !notChecked.Contains(e.EmployeeID) 
    select e; 

如果你有超過4200名員工,上述並不總是有效(你可以選擇2100多個,但是2100個以上的選擇不會被選中,所以它會以任何一種方式爆發),但是我也無法想象4200個不允許你選擇ba的項目列表根據其他度量(即部門),允許像「拉起全體員工在X,Y和Z部門,員工也A,B和C」的查詢:

var metaSelection = departmentList.SelectedItems.Select(x=>x.DepartmentID); 

var exceptions = uiList.SelectedItems.Where(x=>!metaSelection.Contains(x.DepartmentID)) 
         .Select(x=>x.EmployeeID); 

var employees = from e in context.Employees 
    where metaSelection.Contains(e.DepartmentID) 
    || exceptions.Contains(e.EmployeeID) 
+0

您可以使用「join」而不是嵌套查詢來包含示例的另一個版本。只是一個建議,因爲我發佈了類似於你的東西。 – shaunmartin 2011-01-26 20:39:04

0

這裏的問題是2100年參數限制。這是SQL定義的硬限制。不是ADO.NET或LINQ。幾周前我自己跑進了這堵牆。由於LINQ將始終參數化您的查詢,因此無法繞過它。您將不得不批量調用或使用ExecuteQuery。但是,如果您使用ExecuteQuery,請確保您對參數執行自己的驗證以避免SQL注入攻擊。