一点背景知识:
我正在使用不支持某些操作的 Linq 提供程序(MsCrm2011 Linq 提供程序,但并不重要)。
具体来说,它不支持Contains()
在表达式内部。
含义-这样的事情不起作用:var users = DataContext.Users.Where(user => userIds.Contains(user.Id))
.
我找到的解决方案是使用LinqKit的谓词,所以userIds.Contains(...)
我将拥有user.Id == userIds[0] || user.Id == userIds[1] ... || user.Id == userIds[100]
.
为此,我定义了以下函数,它接受任意集合和任意表达式,并对它们应用“或”:
private IQueryable<TCrmEntity> FilterByCollection<TCrmEntity, T>(IQueryable<TCrmEntity> entities, IEnumerable<T> collection, Expression<Func<TCrmEntity, T, bool>> filterFunction)
{
var predicate = PredicateBuilder.False<TCrmEntity>();
predicate = collection.Aggregate(predicate, (current, collectionElement) => current.Or(entity => filterFunction.Invoke(entity,collectionElement)));
var query = entities.AsExpandable()
.Where(predicate);
return query;
}
这样,我可以使用任何一种集合和任何一种表达方式。
例如,查看此测试运行(使用内存中的用户集合):var res = FilterByCollection(users.AsQueryable(), rolesList, (account, role) => account.Role == role)
查找具有给定角色之一的所有用户。
但是,当我运行上面的示例时,我遇到了以下异常 - variable 'entity' of type 'User' referenced from scope '', but it is not defined
。
有任何想法吗?
PS 不确定这有多相关,但是当我实际使用 Crm 数据上下文而不是内存中集合时,我没有收到此错误。:/