【发布时间】:2018-01-26 08:20:00
【问题描述】:
我正在编写一个类似于角色的系统;用户只能查看他们有权访问的数据。这适用于用于表单填充、搜索、列表、报告等的数据。
我计划通过在执行前向 EF 查询添加“WHERE”子句来实现此向 Get 请求添加过滤器的方式。
如果不是因为我们使用泛型,这将很简单。
以前的Get函数是这样的
public class EntityFactory<TEntity, TDto> : IEntityFactory<TEntity, TDto> where TEntity : class
{
private readonly DBContext _context;
private readonly IMapper _mapper;
private DbSet<TEntity> _dbset;
public EntityFactory(DBContext context, IMapper mapper)
{
//...
}
public async Task<List<TDto>> GetAsync()
{
List<TEntity> d = await _dbset.AsNoTracking().ToListAsync();
return _mapper.Map<List<TDto>>(d);
}
}
以及我想做的事:
public async Task<List<TDto>> GetAsync()
{
//If the object implements a special interface
if (i.GetInterfaces().Contains(typeof(IFoo)))
{
//expression to filter the data on a linked table containing the user's Id.
Expression<Func<Bar, bool>> exp = x => x.Foos.Any(a => a.UserId == _user.UserId);
//add the expression to the dbSet
_dbSet = _dbSet.Where(exp);
}
//Execute the get
List<TEntity> d = await q.AsNoTracking().ToListAsync();
//return the converted objects
return _mapper.Map<List<TDto>>(d);
}
但这不起作用!我得到这个编译器错误:
Argument 2: cannot convert from 'System.Linq.Expressions.Expression<System.Func<Bar, bool>>' to 'System.Linq.Expressions.Expression<System.Func<TEntity, int, bool>>'
有没有办法:
- 创建未选中的“动态”查询或
- 将 dbset 更改为所需的类型,应用表达式并将其返回为泛型类型?
【问题讨论】:
-
Queryable.Where已经适用于泛型和表达式。为什么要创造不同的表达方式?为什么要替换 field 而不是创建新查询?如果没有编译错误,你怎么能做到这一点?Where返回一个 IQueryable。还要检查错误的内容 - 它涉及Expression<System.Func<TEntity, int, bool>>。您是否创建了自己的Where?你不需要 -
您是否创建了可能会影响 LINQ 自己的方法的扩展方法?为什么?代码中也有一些非常奇怪的 cmets -
//If the object implements a special interface if (i.GetInterfaces().Contains(typeof(IFoo)))什么对象,为什么不是通用约束?为什么对象是字段而不是参数?您是否将数据访问代码放在实体本身中,或者将其实现为实体的基类?这与使用 ORM 完全相反 -
在泛型方面我仍然是个菜鸟,而且我正在编写由另一个开发人员编写的代码。我得看看他是否创建了额外的扩展方法。
-
@PanagiotisKanavos Where 不是自定义扩展,它来自 System.Linq。但是,有 2 个 where 函数,一个是“预期”的
另一个是 一个。是否有理由调用错误的方法? -
LINQ to EF 没有两个
Where。 LINQ to Objects 可以。 DbSet 没有 有Where,也不能将 IEnumerable 或 IQueryable 分配给 DbSet 字段。不知何故,您在代码中的某个地方混淆了字段名称和类型。
标签: c# entity-framework generics