4

IQueryable と ID の配列を、それらの ID に基づいて IQueryable をフィルター処理するメソッドに渡したいと思います。

ID は long または int のいずれかである可能性があるため、一般的に解決する必要があります。

私は次のことを思いつきました:

public static IEnumerable<T> GetModified<TId, T>(IQueryable<T> objects, TId[] ids) where T : class
{
        return objects.Where(j => ids.Contains((TId)j.GetType().GetProperty("Id").GetValue(j)));
}

残念ながら、例外が発生しています:

LINQ to Entities はメソッド 'System.Object GetValue(System.Object)' メソッドを認識せず、このメソッドはストア式に変換できません。

4

2 に答える 2

6

リフレクションによるプロパティの取得は明らかに SQL に変換できないため、例外は正常です。

私が試みることの 1 つIdは、特定の型のプロパティを公開するジェネリック インターフェイスを作成することです。

public interface HasId<T> {
    T Id { get; set; }
}

これで、エンティティが を実装していると宣言できます。HasId<int>たとえば、Idタイプが の場合intです。

次のステップは、次のようにメソッドを変更することです。

public static IEnumerable<T> GetModified<TId, T>
    (IQueryable<T> objects, TId[] ids) where T : class, HasId<TId>
{
    return objects.Where(j => ids.Contains(j.Id));
}

追加された一般的な制限に注意してください: where T : class, HasId<TId>. これにより、リフレクションに頼る代わりにj.Id、値を返す簡略化された を書くことができます。TId

このコードを実行またはテストしていないことに注意してください。あなたの問題を見たときに得たアイデアに過ぎず、役に立てば幸いです。

アップデート:

インターフェイスを宣言したり、クラスを変更したりする必要のない別の解決策を次に示します。

public static IEnumerable<T> GetModified<TId, T>
    (IQueryable<T> objects, TId[] ids, Expression<Func<T, TId>> idSelector) 
    where T : class
{
    return objects.Where(j => ids.Contains(idSelector(j)));
}

ここで行ったのは、 の特定のインスタンスの をExpression<Func<T, TId>> idSelector返すことができる式であるパラメータを追加することです。IdT

次のようにメソッドを呼び出します。

var modified = GetModified(dbObjects, yourIdArray, entity => entity.Id);

(3 番目のパラメーターのみが新しいものです。他のパラメーターは現在の状態のままにしてください)。

繰り返しますが、ここにVSを備えたコンピューターがないため、これが機能するか、コンパイルされるかどうかはテストしていません:(。

于 2013-09-21T08:32:44.783 に答える
3

Entity Framework は、 などの .NET メソッドの一部をサポートしGetValue()ていません。これは、SQL に変換されないためです (これは、実際に に実行されるコードです。リフレクションを実行する前に、CLR オブジェクトを取得するためにIQueryable呼び出してみてください。ToList

public static IEnumerable<T> GetModified<TId, T>(IQueryable<T> objects, TId[] ids) where T : class
{
    return objects.ToList().Where(j => ids.Contains((TId)j.GetType().GetProperty("Id").GetValue(j)));
}
于 2013-09-21T08:27:25.040 に答える