c# - EntityFramework6/Npgsql : how to translate orderBy nulls last into SQL query

标签 c# postgresql entity-framework-6 npgsql

我正在使用 EntityFramework6.Npgsql 并且正在处理具有数百万条记录的表。一些实体有一个 timestamp/DateTime允许 null 的列值。用户经常需要在此列上排序并希望显示 null asc 中的值最后和 desc排序。该列有两个索引用于两种排序类型,它们都设置为 nulls last

我知道在 SQL 中我可以添加 order by "DateColumn" desc nulls last并且 postgres 使用适当的索引和查询返回(分页,例如 25 条记录)结果在几毫秒内。

然而,对于 EntityFramework,为了最后对空值进行降序排序,我必须添加如下内容:

entities.MyEntity
    .OrderByDescending(e => e.DateColumn.HasValue)
    .ThenByDescending(e => e.DateColumn)

然而,这会转化为一个查询,其中包含类似这样的排序内容:

SELECT 
    CASE
        WHEN ("Extent1"."DateColumn" IS NOT NULL) THEN (TRUE)
        ELSE (FALSE)
    END AS "C1"

...

ORDER BY "C1", "DateColumn" DESC

它按预期工作,但查询需要几秒钟(而不是几毫秒)才能执行,因为它无法使用索引。

我尝试用相同的表达式向列添加索引,但 postgres 在执行查询时似乎没有使用索引。

在 EntityFramework/Npgsql 中编写可以转换为所需 SQL (order by "DateColumn" desc nulls last) 的查询时,我有哪些选择?有没有办法拦截/覆盖 Linq 查询如何转换为 SQL?

最佳答案

回答我自己的问题...

虽然仍然无法让 Linq 生成以 nulls last 排序的 SQL 查询,但我能够为 null 检查和日期列本身创建一个组合索引,该索引由邮政系统:

CREATE INDEX "MyTable_IX_DateCombined"
  ON "MyTable"
  USING btree
  ((
  CASE
    WHEN "DateColumn" IS NOT NULL THEN true
    ELSE false
  END) DESC, "DateColumn" DESC);

由于在任何一种情况下我都必须创建一个额外的索引,所以我认为这个解决方案在这一点上已经足够好了。

关于c# - EntityFramework6/Npgsql : how to translate orderBy nulls last into SQL query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48872455/

相关文章:

c# - 为什么不调用重载方法?

c# - 单例设计模式的优点是什么

c# - asp net web api 身份验证 token 过期?

django-fts : How to create indexes for psql

sql - 如何获得 Postgres 中两个字段的 MIN()?

c# - 将 Insert into select 翻译成 Entity Framework 6

C# 和 Word - 替换为格式

postgresql - 从 SQL 查询中去除括号

c# - DDD 项目的数据库优先模型中的复杂类型

c# - 在连接的场景中添加一个新项目, Entity Framework