A little background:
I'm using a Linq provider (MsCrm2011 Linq provider, but doesn't really matter) that doesn't support certain operations.
Specifically, it doesn't support Contains()
inside an expression.
Meaning- something like this will not work: var users = DataContext.Users.Where(user => userIds.Contains(user.Id))
.
The solution I've found for it was to use LinqKit's predicate, so instead of userIds.Contains(...)
I'll have user.Id == userIds[0] || user.Id == userIds[1] ... || user.Id == userIds[100]
.
To this end, I've defined the following function, which takes an arbitrary collection and arbitrary expression, and applies the 'Or' on them:
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;
}
this way, I can use any kind of collection and any kind of expression.
For example, see this test run (using an in-memory users collection): var res = FilterByCollection(users.AsQueryable(), rolesList, (account, role) => account.Role == role)
to find all users that have one of the given roles.
However, I'm getting the following exception when I'm running the above example- variable 'entity' of type 'User' referenced from scope '', but it is not defined
.
Any ideas?
P.S. not sure how relevant this is, but when I'm actually using the Crm data context instead of an in-memory collection, I'm not getting this error. :/