EF Core TPH继承场景下忽略鉴别器查询全表所有实体模型的方法
EF Core TPH继承模式忽略鉴别器查询解决方案
方案1:基于基类DbSet查询(推荐)
基类WorkflowInstance对应的DbSet默认不会添加固定鉴别器过滤条件,会返回表中所有继承层级的实体,可直接组合基类通用条件和派生类专属条件:
// 替换为你实际的过滤时间 var targetDate = Instant.FromUtc(2024, 1, 1, 0, 0); var targetUserId = Guid.Parse("你的目标UserId"); var query = _dbContext.WorkflowInstances // 基类通用过滤 .Where(w => w.FinishedAt > targetDate) // 派生类UserId过滤,基类实体不会命中该条件 .Where(w => w is CustomWorkflowInstance cw && cw.UserId == targetUserId); var allMatchInstances = query.ToList(); // 可单独提取派生类实例 var customInstances = allMatchInstances.OfType<CustomWorkflowInstance>().ToList();
该方案生成的SQL不会额外限制鉴别器取值,完全按照你指定的条件过滤全表数据,映射规则符合EF Core默认约定,不会出现类型映射异常。
方案2:忽略查询过滤器直接查询派生类DbSet
如果必须从CustomWorkflowInstance的DbSet出发查询,可通过IgnoreQueryFilters方法移除默认的鉴别器过滤:
var targetDate = Instant.FromUtc(2024, 1, 1, 0, 0); var targetUserId = Guid.Parse("你的目标UserId"); var query = _dbContext.CustomWorkflowInstances // 移除默认鉴别器过滤,同时会移除你配置的其他全局查询过滤器,如有需要请手动补全 .IgnoreQueryFilters() .Where(cw => cw.FinishedAt > targetDate && cw.UserId == targetUserId); var result = query.ToList();
注意:该方案返回的结果中,原本鉴别器为0的基类数据会被强制映射为
CustomWorkflowInstance类型,其UserId属性为默认值Guid.Empty,请根据业务逻辑判断是否接受该映射结果。
方案3:原生SQL查询
如果需要更灵活的查询逻辑,可直接编写原生SQL执行:
var targetDate = Instant.FromUtc(2024, 1, 1, 0, 0); var targetUserId = Guid.Parse("你的目标UserId"); var sql = @"SELECT * FROM WorkflowInstances WHERE FinishedAt > {0} AND (Discriminator = 1 AND UserId = {1} OR Discriminator = 0)"; var result = _dbContext.WorkflowInstances .FromSqlRaw(sql, targetDate, targetUserId) .ToList();
内容的提问来源于stack exchange,提问作者AmineMraihi
相关产品推荐
相关产品推荐

