You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core自定义Owned类型DbDateTime无法在LINQ查询中转换的问题

问题:EF Core自定义DateTimeOffset封装类型无法在LINQ查询中转成SQL

背景

我们正在从SQL Server迁移到PostgreSQL。SQL Server支持datetimeoffset列类型,但PostgreSQL没有对应类型,因此我们将该类型拆分为两列:

  • UTC 日期时间(timestamptz类型)
  • 偏移分钟数(smallint类型)

我们使用EF Core 7的Owned实体类型,把这两列封装到DbDateTime类中,该类包含一个标记为[NotMapped]的DateTimeOffset属性,方便业务逻辑处理日期时间。

问题现象

在LINQ查询中使用DbDateTime类型时,EF Core无法将其转换为SQL语句。示例查询代码如下:

DateTime expiredDateTime = DateTime.UtcNow.AddDays(-30);
var items = context.ReceivedPackages.Where(i => i.ReceivedAt < expiredDateTime).ToList();

相关类定义

ReceivedPackage类

public class ReceivedPackage
{
    public ReceivedPackage()
    {
        Identifier = Guid.NewGuid();
    }

    public Guid Identifier { get; set; }

    public DbDateTime ReceivedAt { get; set; }
}

DbDateTime类

[Owned]
public class DbDateTime
{
    // 完整代码保持不变
}

尝试过的无效方案

我们尝试通过实现ExpressionVisitor来解决问题,但该方案未生效,甚至没有进入VisitBinary或VisitMember方法。相关代码如下:

修改后的LINQ查询

DateTime expiredDateTime = DateTime.UtcNow.AddDays(-30);
var items = context.ReceivedPackages
  .InterceptDbDateTimeExpressions()
  .Where(i => i.ReceivedAt < expiredDateTime).ToList();

扩展方法定义

public static IQueryable<T> InterceptDbDateTimeExpressions<T>(this IQueryable<T> source)
{
    var visitor = new DbDateTimeExpressionVisitor();
    var newExpression = visitor.Visit(source.Expression);
    return source.Provider.CreateQuery<T>(newExpression);
}

ExpressionVisitor类定义

public class DbDateTimeExpressionVisitor : ExpressionVisitor
{
    // 完整代码保持不变
}

求助需求

现寻求可行方案,解决自定义DbDateTime类型无法在LINQ查询中被EF Core转换为SQL的问题。


内容的提问来源于stack exchange,提问作者Patrick Leijser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:49:52