如何执行包含条件运算符的LINQ to SQL编译查询?

时间:2014-02-25 19:22:19

标签: c# .net linq-to-sql linq.compiledquery

我需要编译包含条件“?:”运算符的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包含多个元素。”

堆栈跟踪是:

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() ...

任何人都可以提供一种方法来执行此操作吗?由于我无法进入的原因,我无法将此条件逻辑移出表达式之外 - 它必须是已编译查询的一部分。

1 个答案:

答案 0 :(得分:1)

这可能是一个错误。该错误是他们没有给您一个错误,您无法在多个查询之间进行运行时切换。他们可能从未打算使用CompiledQuery.Compile

编译两个查询,或:UserId >= (option ? 0 : 5) && UserId < (option ? 5 : int.MaxValue)。这个谓词仍然是SARGable。