解决 LINQ 2 SQL 合并限制
Working around LINQ 2 SQL Coalesce limitation
我正在尝试将现有的 T-SQL 查询转换为 C# Linq2Sql 查询,但生成的 T-SQL 查询生成的 COALESCE 链嵌套太深.有没有办法在不调用动态 T-SQL?
的情况下解决这个问题
考虑 Sql 服务器中的 table,如下所示:
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 滥用了合并 (??) 运算符 - 它一直将每个操作嵌套为内部和单独的合并 (...),本质上将其视为 IsNull(.. .) 只需要两个参数。
问题是 SQL 服务器对这种合并的嵌套深度有限制(10 层),而且我的查询有更多的参数。这意味着我的查询在运行时崩溃并出现以下错误:
SqlException: Case expressions may only be nested to level 10.
原来的T-SQL查询只是简单的把参数正常的堆叠起来,比如:COALESCE(a, b, c, d, e, f ,g ...) 但是我找不到一个强制 Linq2Sql 执行相同操作的方法。如有任何帮助或提示,我们将不胜感激!
当然,实际查询涉及大量的table和连接,以上伪代码仅供参考。
你可以试试这个
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 列。但我承认这很奇怪...
我正在尝试将现有的 T-SQL 查询转换为 C# Linq2Sql 查询,但生成的 T-SQL 查询生成的 COALESCE 链嵌套太深.有没有办法在不调用动态 T-SQL?
的情况下解决这个问题考虑 Sql 服务器中的 table,如下所示:
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 滥用了合并 (??) 运算符 - 它一直将每个操作嵌套为内部和单独的合并 (...),本质上将其视为 IsNull(.. .) 只需要两个参数。
问题是 SQL 服务器对这种合并的嵌套深度有限制(10 层),而且我的查询有更多的参数。这意味着我的查询在运行时崩溃并出现以下错误:
SqlException: Case expressions may only be nested to level 10.
原来的T-SQL查询只是简单的把参数正常的堆叠起来,比如:COALESCE(a, b, c, d, e, f ,g ...) 但是我找不到一个强制 Linq2Sql 执行相同操作的方法。如有任何帮助或提示,我们将不胜感激!
当然,实际查询涉及大量的table和连接,以上伪代码仅供参考。
你可以试试这个
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 列。但我承认这很奇怪...