EF Core如何在OnModelCreating中配置带自定义过滤规则的集合导航属性
要实现你需要的导航属性效果,首先要明确:EF Core 中常规的外键关系仅支持等值匹配,无法直接实现 Id > 当前记录Id 这种范围比较的关联条件,你之前的两种尝试思路本身就不符合EF Core的配置规则:
HasComputedColumnSql仅适用于普通字段属性,无法用来配置集合导航属性HasMany+ 外键/主键配置仅支持等值关联,不支持大小比较逻辑
以下是两种可行的实现方案:
方案一:使用过滤式Include(推荐,适用于EF Core 5.0及以上版本)
第一步先在OnModelCreating中配置基础的自引用关系,固定过滤Type为Take的条件:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Transaction>() .HasMany(t => t.Takes) .WithOne() // 关联两个实体的ForeignId做等值匹配 .HasForeignKey(t => t.ForeignId) .HasPrincipalKey(t => t.ForeignId) // 全局过滤该关系下仅返回Type为Take的记录 .HasFilter("[Type] = 'Take'"); }
第二步查询的时候通过带过滤的Include补充Id > 当前记录Id的条件即可:
var transaction = dbContext.Transactions .Include(t => t.Takes.Where(tt => tt.Id > t.Id)) .SingleOrDefault(t => t.Id == 2);
该方案执行后transaction.Takes就会返回你期望的ID为5、6的两条记录。
方案二:投影查询(兼容所有EF Core版本)
如果你的EF Core版本低于5.0不支持过滤式Include,可以直接用投影的方式手动构造结果,不需要额外配置导航关系:
var transaction = dbContext.Transactions .Where(t => t.Id == 2) .Select(t => new Transaction { Id = t.Id, ForeignId = t.ForeignId, Type = t.Type, Quantity = t.Quantity, Takes = dbContext.Transactions .Where(tt => tt.ForeignId == t.ForeignId && tt.Id > t.Id && tt.Type == "Take") .ToList() }) .SingleOrDefault();
内容的提问来源于stack exchange,提问作者Jogge
相关产品推荐
相关产品推荐

