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
相关产品推荐
相关产品推荐

