2008-09-17 18 views
6

MVCの店頭に触発されている最新のプロジェクトでは、IQueryableの拡張メソッドを使用して結果をフィルタリングしています。インターフェイスで機能しない拡張メソッド

私はこのインターフェイスを持っています。

IPrimaryKey 
{ 
    int ID { get; } 
} 

と私は、この拡張メソッドを持っている

public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id) 
{ 
    return source(obj => obj.ID == id); 
} 

のは、私がIPrimaryKeyを実装するクラス、SimpleObjがあるとしましょう。私はSimpleObjのIQueryableを持っているとき、GetByIDメソッドは存在しません。私は明示的に、IPrimaryKeyのIQueryableとして理想的ではありません。

ここに何か不足していますか?

答えて

13

それは動作します、正しいときに。 cfedukeのソリューションが動作します。しかし、あなたは一般的なIPrimaryKeyインタフェースを作成する必要はありませんが、実際には、あなたは、すべてのあなたの元の定義を変更する必要はありません。

public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey 
{ 
    return source(obj => obj.ID == id); 
} 
+0

優れた - 私は、未承認のオリジナルの答えをしました。私は明日これを試してみる。あなたのおかげです。 – Kirschstein

+1

私の答えは間違っていなかったと言いたいのですが、それが彼のコードがうまくいかなかった理由です。私は解決策を見つけるのに時間を割けていませんでした。あなたのより良い答えに投票しました。 –

+0

ただ非常にマイナーなポイント:IPrimaryKey //より良い統合:それは(本のIQueryable ソース... T – Kirschstein

2

ジェネリックスに継承パターンに従う能力がないため、これは機能しません。すなわち、 IQueryable <SimpleObj>はIQueryableを<IPrimaryKey>

4

編集の継承ツリーではありません。Konradのソリューションは、そのはるかに簡単に優れています。以下のソリューションは機能しますが、継承階層を辿ることなくクラスのメソッドがリフレクションによって取得されるObjectDataSourceに似た状況でのみ必要です。明らかに、それはここで起こっていない。

これは私がObjectDataSourceので作業するためのカスタムエンティティフレームワーク・ソリューションを設計したときに同様のパターンを実装するために持っていた、可能です:使用の

public interface IPrimaryKey<T> where T : IPrimaryKey<T> 
{ 
    int Id { get; } 
} 

public static class IPrimaryKeyTExtension 
{ 
    public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T> 
    { 
     return source.Where(pk => pk.Id == id).SingleOrDefault(); 
    } 
} 

public class Person : IPrimaryKey<Person> 
{ 
    public int Id { get; set; } 
} 

スニペット:

var people = new List<Person> 
{ 
    new Person { Id = 1 }, 
    new Person { Id = 2 }, 
    new Person { Id = 3 } 
}; 

var personOne = people.AsQueryable().GetById(1); 
関連する問題