如何在Entity Framework中使用DbContext查询与指定ID同列值重复的所有ID
解决方案
方案1:强类型约束方案(推荐)
首先定义公共接口,让需要用到该方法的实体类实现接口:
public interface IHasNameId { long Id { get; set; } string Name { get; set; } }
修改仓储类的泛型约束:
public class Repository<T> : IRepository<T> where T : class, IHasNameId
新增需求方法:
public async Task<List<long>> GetSameNameOtherIdsAsync(long inputId) { // 查找输入ID对应的实体 var targetEntity = await GetByIdAsync(inputId); if (targetEntity == null) return []; // 查询同名称且排除自身的所有ID return await _dbFactory.DbContext .Set<T>() .Where(x => x.Name == targetEntity.Name && x.Id != inputId) .Select(x => x.Id) .ToListAsync(); }
方案2:无强类型约束方案
如果不想修改原有泛型约束,可以用EF提供的动态属性访问方法实现,不需要改动原有代码结构:
using Microsoft.EntityFrameworkCore; public async Task<List<long>> GetSameNameOtherIdsAsync(long inputId) { var dbSet = _dbFactory.DbContext.Set<T>(); var targetEntity = await dbSet.FindAsync(inputId); if (targetEntity == null) return []; // 动态获取目标实体的Name值 var targetName = _dbFactory.DbContext .Entry(targetEntity) .Property<string>("Name") .CurrentValue; // 动态构造查询 return await dbSet .Where(x => EF.Property<string>(x, "Name") == targetName && EF.Property<long>(x, "Id") != inputId) .Select(x => EF.Property<long>(x, "Id")) .ToListAsync(); }
用到的DbContext/EF核心方法
Set<T>():获取对应实体类型的可查询数据集,是EF LINQ查询的基础FindAsync<T>():按主键查询实体,会优先命中上下文本地缓存,性能优于普通LINQ过滤查询Entry().Property():动态读取实体的指定属性值,适合泛型场景下的弱类型访问EF.Property<TProperty>():在LINQ查询中动态访问实体属性,EF可将该语法正常翻译为SQL,不会触发客户端评估ToListAsync():异步执行查询并返回结果集合,符合异步编程规范
内容的提问来源于stack exchange,提问作者Nisha
相关产品推荐
相关产品推荐

