EFエンティティをバッチでロードするための非常に一般的な方法を作成しようとしています。Containsメソッドを使用してSQLINステートメントを生成します。式全体を渡せば機能しますが、式を動的に作成しようとすると、「LINQ式ノードタイプ'Invoke'はLINQtoEntitiesではサポートされていません」というメッセージが表示されます。つまり、EFは私が任意のメソッドを呼び出していると見なし、それをSQLに変換できないことを意味しますが、基になる式を理解する方法を理解できません。
したがって、このようなことを行うと(関連するスニペットを表示するだけです):
関数宣言:
public static List<T> Load<T>(IQueryable<T> entityQuery, int[] entityIds, Func<T, int> entityKey, int batchSize = 500, Func<T, bool> postFilter = null) where T : EntityObject
{
var retList = new List<T>();
// Append a where clause to the query passed in, that will use a Contains expression, which generates a SQL IN statement. So our SQL looks something like
// WHERE [ItemTypeId] IN (1921,1920,1922)
// See http://rogeralsing.com/2009/05/21/entity-framework-4-where-entity-id-in-array/ for details
Func<int[], Expression<Func<T, bool>>> containsExpression = (entityArray => (expr => entityArray.Contains(entityKey(expr))));
// Build a new query with the current batch of IDs to retrieve and add it to the list we are returning
newQuery = entityQuery.Where<T>(containsExpression(entityIds));
retList.AddRange(newQuery.ToList());
return retList;
}
関数を呼び出す:
var entities = BatchEntity.Load<ItemType>(from eItemType in dal.Context.InstanceContainer.ItemTypes
select eItemType
, itemTypeData
, (ek => ek.ItemTypeId)
);
「LINQ式ノードタイプ'Invoke'はLINQtoEntitiesではサポートされていません。」というメッセージが表示されます。
しかし、これに変更すると、次のようになります。
関数宣言:
public static List<T> Load<T>(IQueryable<T> entityQuery, int[] entityIds, Func<int[], Expression<Func<T, bool>>> containsExpression, int batchSize = 500, Func<T, bool> postFilter = null) where T : EntityObject
{
var retList = new List<T>();
// Build a new query with the current batch of IDs to retrieve and add it to the list we are returning
newQuery = entityQuery.Where<T>(containsExpression(entityIds));
retList.AddRange(newQuery.ToList());
return retList;
}
関数を呼び出す:
var entities = BatchEntity.Load<ItemType>(from eItemType in dal.Context.InstanceContainer.ItemTypes
select eItemType
, itemTypeData
, (entityArray => (ek => entityArray.Contains(ek.ItemTypeId)))
);
正常に動作します。EFにもっと一般的なバージョンを理解させる方法はありますか?