ちょっとした背景:
特定の操作をサポートしていない
Linq プロバイダー ( MsCrm2011 Linq provider ですが、実際には問題ではありません) を使用しています。
具体的には、式の中ではサポートされていません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]
.
この目的のために、任意のコレクションと任意の式を取り、それらに「Or」を適用する次の関数を定義しました。
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データコンテキストを実際に使用している場合、このエラーは発生しません. :/