【发布时间】:2020-04-20 01:04:53
【问题描述】:
问题是 - 我得到以下错误:
案例表达式只能嵌套到第 10 级。
当我尝试将以下 LINQ 代码与 EF 核心一起使用时
var extendedResult = result.Select(p => new
{
readModelFields = p,
sortKey =
p.CaseState == CaseState.Scheduled.ToString() ? 1 :
p.CaseState == CaseState.Queued.ToString() ? 2 :
p.CaseState == "Investigation" ? 3 :
p.CaseState == "Awaiting Customer" ? 4 :
p.CaseState == "State 5" ? 5 :
p.CaseState == "State 6" ? 6 :
p.CaseState == "State 7" ? 7 :
p.CaseState == "State 8" ? 8 :
p.CaseState == "State 9" ? 9 :
p.CaseState == "State 10" ? 10 :
p.CaseState == "State 11" ? 11 :
p.CaseState == "Rejected" ? 12 :
p.CaseState == "Blocked" ? 13 :
p.CaseState == "Postponed" ? 14 :
15
});
return IsAscending(query.SortDirection)
? extendedResult.OrderBy(p => p.sortKey).Select(p => p.readModelFields)
: extendedResult.OrderByDescending(p => p.sortKey).Select(p => p.readModelFields);
这个问题是由 SQL 生成 SQL 的方式引起的(这是一个结果)
exec sp_executesql N'SELECT [o].[Id], [o].[Owner], [o].[CaseState], [o].[LastActionDate], [o].[CountryCode], [o].[Name], [o].[Risk]
FROM [dbo].[OpenCases] AS [o]
ORDER BY CASE
WHEN [o].[CaseState] = N''Scheduled'' THEN 1
ELSE CASE
WHEN [o].[CaseState] = N''Queued'' THEN 2
ELSE CASE
WHEN [o].[CaseState] = N''Investigation'' THEN 3
ELSE CASE
WHEN [o].[CaseState] = N''Awaiting Customer'' THEN 4
ELSE CASE
WHEN [o].[CaseState] = N''State 6'' THEN 6
ELSE CASE
WHEN [o].[CaseState] = N''State 7'' THEN 7
ELSE CASE
WHEN [o].[CaseState] = N''State 8'' THEN 8
ELSE CASE
WHEN [o].[CaseState] = N''State 9'' THEN 9
ELSE CASE
WHEN [o].[CaseState] = N''State 10'' THEN 10
ELSE CASE
WHEN [o].[CaseState] = N''State 11'' THEN 11
ELSE CASE
WHEN [o].[CaseState] = N''Rejected'' THEN 12
ELSE CASE
WHEN [o].[CaseState] = N''Blocked'' THEN 13
ELSE CASE
WHEN [o].[CaseState] = N''Postponed'' THEN 14
ELSE 15
END
END
END
END
END
END
END
END
END
END
END
END
END DESC
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__p_0 int,@__p_1 int',@__p_0=0,@__p_1=2147483647
我想要的是 EF 构建这样的查询:
...
ORDER BY
CASE
WHEN CaseState = "Investigation" THEN 3
WHEN CaseState = "State 5" THEN 5
WHEN CaseState = "State 6" THEN 6
WHEN CaseState = "State 7" THEN 7
.......
WHEN CaseState = "Postponed" THEN 14
END desc
【问题讨论】:
-
您对 SQL 的生成方式影响不大。最简单的方法是将“状态 5”转换为“5”的数据库表中,然后使用 Join。这将是数据库风格。非常棘手的事情:定义一个具有相应值的 Enum,这将使用字符串到 int 转换进行序列化,但它不适用于字符串中的空格。
-
感谢您的支持。虽然 - 我在这里专门发布了这个问题,以了解是否有可能以某种方式影响它。如果不是 - 那么我将不得不按照您建议的方式在 SQL 中添加列或表。现在 - 我正在寻找并回答如何重写 LINQ 或如何告诉 EF 以不同的方式构建“CASE When Then”。
-
一般来说是可以的,但并不容易。 SQL 提供程序有注入机制。仅当您在不同场景中经常需要它时才值得。您也可以只使用 RawSQL-Query 发送 SQL,或者在从数据库加载字符串后,您可以在 LINQ 中将字符串转换为整数到对象(或使用自定义 IComparer)。
-
我肯定会使用将原始 sql 传递给 EF 上下文并利用安全查询参数化或几乎任何其他方法,而不是仅向表中添加额外的列以使使用 EF 更容易一些。
-
在Issues - EntityFrameworkCore 提出建议,允许将新的 C# 8.0 switch 表达式转换为 SQL。
expr switch { e1 => ret1, e2 => ret2, _ => ret3 }将转换为CASE expr WHEN e1 THEN ret1 WHEN e2 THEN ret2 ELSE ret3 END。
标签: c# sql-server linq entity-framework-core