我们正在迁移一些代码以使用Entity Framework并且有一个尝试对Nullable字段进行排序的查询,并提供一个默认排序值,使用Nullable.GetValueOrDefault(T)函数将值设置为null。
但是,执行时会返回以下错误:
LINQ to Entities无法识别方法'Int32 GetValueOrDefault(Int32)'方法,并且此方法无法转换为商店表达式。
查询如下:
int magicDefaultSortValue = 250;
var query = context.MyTable.OrderBy(t => t.MyNullableSortColumn
.GetValueOrDefault(magicDefaultSortValue));
来自this answer I can see that there is a way to provide "translations" within your EDMX。我们可以为这个合并函数编写类似的翻译吗?
注意:当我尝试时,??
合并运算符而不是查询中的GetValueOrDefault它确实有效。那么也许是什么使得这项工作可以被利用?
答案 0 :(得分:12)
我相信你找到了答案。当您使用??
时,EF会使用CASE
生成SQL,以便在值为null
时选择排序值,然后对其进行排序。
MyTable.OrderBy (t => t.MyNullableSortColumn ?? magicDefaultSortValue).ToArray();
将生成以下sql:
-- Region Parameters
DECLARE p__linq__0 Int = 250
-- EndRegion
SELECT
[Project1].[MyColumn1] AS [MyColumn1],
[Project1].[MyNullableSortColumn] AS [MyNullableSortColumn]
FROM ( SELECT
CASE WHEN ([Extent1].[MyNullableSortColumn] IS NULL) THEN @p__linq__0 ELSE [Extent1].[MyNullableSortColumn] END AS [C1],
[Extent1].[MyColumn1] AS [MyColumn1],
[Extent1].[MyNullableSortColumn] AS [MyNullableSortColumn]
FROM [dbo].[MyTable] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[C1] ASC
顺便说一下,我建议使用LINQPad,它可以让您使用EF模型并查看正在生成的sql。此外,了解EntityFunctions类和SqlFunctions类是有帮助的,因为它们提供了对几个有用功能的访问。