2014-02-25 35 views
2

我需要編譯一個包含條件「?:」運算符的LINQ-to-SQL查詢。我能夠編譯這樣的查詢,但問題是,當我嘗試執行它時會失敗。如何執行包含條件運算符的LINQ to SQL編譯查詢?

下面是一個簡單的攝製:

MyContext myContext = new MyContext(sqlConnection); 
myContext.Log = Console.Out; 

var cq = CompiledQuery.Compile(
     (MyContext context, bool option) => 
       option ? context.GetTable<User>().Where(x => x.UserId > 5) 
         : context.GetTable<User>().Where(x => x.UserId < 5)); 

//Crashes when trying to invoke. 
cq.Invoke(myContext, true); 

控制檯輸出顯示預期的SQL語句執行:

SELECT [t0].[UserId],... 
FROM [dbo].[User] AS [t0] 
WHERE [t0].[UserId] > @p0 
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [5] 

但似乎執行,而試圖枚舉結果從設置失敗數據庫。

異常是一個InvalidOperationException,消息「Sequence contains more more than one。」。

堆棧跟蹤是:

at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 
at Read_User(ObjectMaterializer`1) 
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext() 
at Program.Main() ... 

任何人都可以提供一種方式來得到這個執行?由於我無法理解的原因,我無法將該條件邏輯移到表達式之外 - 它必須是已編譯查詢的一部分。

+0

可能是一個錯誤。錯誤是他們不會給你一個錯誤,你不能在多個查詢之間進行運行時切換。他們可能從來沒有打算使用CompiledQuery.Compile。 – usr

+0

是的,這就是我所害怕的。但是,由於sql語句被正確執行,我想也許這是可以做到的。 –

+1

編譯兩個查詢,或者:'UserId> =(option?0:5)&& UserId <(option?5:int.MaxValue)'。這個謂詞仍然是SARGable。 – usr

回答

1

這可能是一個錯誤。錯誤是他們不會給你一個錯誤,你不能在多個查詢之間進行運行時切換。他們可能從未打算這樣使用CompiledQuery.Compile

編譯兩個查詢,或者:UserId >= (option ? 0 : 5) && UserId < (option ? 5 : int.MaxValue)。這個謂詞仍然是SARGable。