如何解决在使用泛型的 ef 核心选择语句中选择命名字段
我有下面的方法将新记录插入我的数据库
public static async Task SaveDataToEntitySetAsync<TEntity>(DbContext context,List<TEntity> list)
where TEntity : class
{
if(list.Any() == false)
return;
var dbSet = context.Set<TEntity>();
var existingData = await dbSet.Select(x=>x.Id).ToListAsync();
list.RemoveAll(x => existingData.Contains(x.Id));
await dbSet.AddRangeAsync(list);
}
如果我不使用泛型,上面的逻辑就是我想要做的
如何将其转换为适用于泛型的语法?此语法在通用上下文中不起作用,因为 .Id 无效
我使用的是 EF Core,所以当一条记录添加到表中时,EF Core 会自动将记录添加到关联的外键表中
这种方法的问题在于,我会为上下文中的每个表调用此方法。
假设添加了一位英国客户。这很好,客户被添加,并且英国国家被添加(假设它尚未存在)
我还有我保存到数据库中的所有国家的摘录。显然这现在会中断,因为英国已经被拯救了
因此,我试图从我的国家/地区列表中删除已存在于数据库中的任何项目
我所有的实体都来自一个 BaseEntity(这是定义 Id 的地方),但我不知道如何利用这个事实
保罗
解决方法
由于您的实体已经从具有 Id
属性的同一个基类继承,您可以将泛型类型限制为:
where TEntity : BaseEntity
,
您可以传递一个 Expression<Func<TEntity,TKey>> keyExtractor
lambda 表达式,例如 x => x.Id
:
public static async Task SaveDataToEntitySetAsync<TEntity,TKey>(DbContext context,List<TEntity> list,Expression<Func<TEntity,TKey>> keyExtractor)
where TEntity : class
{
if (list.Any() == false)
return;
var dbSet = context.Set<TEntity>();
var existingData = await dbSet.Select(keyExtractor).ToListAsync();
Func<TEntity,TKey> keyExtractorCompiled = keyExtractor.Compile();
list.RemoveAll(x => existingData.Contains(keyExtractorCompiled(x)));
await dbSet.AddRangeAsync(list);
}
然后:
await SaveDataToEntitySetAsync(...,x => x.Id);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。