我试图将现有的T-SQL查询转换为C#Linq2Sql查询,但生成的T-SQL查询会产生一个嵌套太深的COALESCE链。有没有办法在不调用动态T-SQL的情况下解决这个问题?
考虑一下Sql Server中的表,如下所示:
create table MyTable(id int, a int, b int, c int, d int)
现在这个C#查询:
from t in MyTable select new { id = id, val = t.a ?? t.b ?? t.c ?? t.d };
这导致以下T-SQL:
SELECT [t0].[id] AS [id], COALESCE([t0].[a],COALESCE([t0].[b],COALESCE([t0].[c],[t0].[d]))) AS [val]
FROM [Case] AS [t0]
正如您所看到的,Linq2Sql滥用了coalesce(??)运算符 - 它将每个操作嵌套为内部和单独的Coalesce(...),基本上将其视为IsNull(...),它只接受两个参数。
问题在于SQL Server对这种合并的嵌套程度有限(10级),而且我的查询有更多的参数。这意味着我的查询在运行时崩溃并出现以下错误:
SqlException:Case表达式只能嵌套到10级。
原始的T-SQL查询只是简单地堆叠参数,例如:COALESCE(a,b,c,d,e,f,g ......)但我找不到强制Linq2Sql的方法做同样的事。任何帮助或提示将不胜感激!
当然,实际查询涉及大量的表和连接,上面的伪代码仅供参考。
答案 0 :(得分:1)
你可以试试这个
from t in MyTable select new { id = id, val = (t.a ?? t.b) ?? (t.c ?? t.d) };
它会生成
COALESCE(COALESCE([t0].[a],[t0].[b]),COALESCE([t0].[c],[t0].[d]))
所以它应该扩展到1024列。但我承认这很奇怪......