2009-08-08 3 views
5

私はLINQ to SQLベースのリポジトリを作成しています。ここでは、intパラメータを使用してGetByIDを許可します。署名は次のとおりです。LINQ to SQLを使用してプライマリキーを決定

public T GetByID(int id) 
{ 
    // Return 
    return _dataContext.GetTable<T>() ....; 
} 

テーブルの主キーの名前が異なります。私がしたいのは、プライマリキーが何であるかを各Tに対して動的に決定し、それにinteger = idの値を問い合わせることです。どのアイデアをどのように最適にこれをプルするには?

+0

申し訳ありませんが、私の答えはダメだった - 私は、データベースを照会 '表'、とオブジェクトのインメモリリストを混同しました。この質問は以前に回答済みでした:http://stackoverflow.com/questions/735140/c-linq-to-sql-refectoring-this-generic-getbyid-method –

答えて

3

個人的には、メソッドを提供するのは、Func<int,T>セレクタ引数をとる方が簡単だと思います。次に、そのテーブルのIDに基づいて選択するセレクタを含め、任意のセレクタを指定できます。

public abstract class Repository<T> where T : class 
{ 
    public abstract T GetById(int id); 
    public T SingleOrDefault(Func<int,T> selector) 
    { 
      return _dataContext.GetTable<T>().SingleOrDefault(selector); 
    } 
} 

は使用方法:

var myObj = repos.SingleOrDefault<MyClass>(c => c.MyClassID == id); 

A、厳密に型指定されたリポジトリーはその後、()だけint以外の種類をサポートし、以下のような

public class MyClassRepository : Repository<MyClass> 
{ 
    public override MyClass GetById(int id) 
    { 
     return this.SingleOrDefault(c => c.MyClassID == id); 
    } 
} 
+0

実際に渡された 'id 'c.MyClassID'に対する値? – GregL

+0

@GregL - 良いキャッチ。一定。 – tvanfosson

10

何かを(GetByIdを実装するために、このメソッドを使用することができ、デフォルトはint)。重要なことに、反射を介してAttributeのデータを見ることの罠に陥ることはありません。 LINQツーSQLはあまりにも属性なしのオブジェクトをサポートしています。

public static TEntity Get<TEntity>(this DataContext dataContext, int id) 
     where TEntity : class 
{ 
    return Get<TEntity, int>(dataContext, id); 
} 
public static TEntity Get<TEntity, TKey>(this DataContext dataContext, TKey id) 
    where TEntity : class 
{ 
    // get the row from the database using the meta-model 
    MetaType meta = dataContext.Mapping.GetTable(typeof(TEntity)).RowType; 
    if (meta.IdentityMembers.Count != 1) throw new InvalidOperationException(
     "Composite identity not supported"); 
    string idName = meta.IdentityMembers[0].Member.Name; 

    var param = Expression.Parameter(typeof(TEntity), "row"); 
    var lambda = Expression.Lambda<Func<TEntity, bool>>(
     Expression.Equal(
      Expression.PropertyOrField(param, idName), 
      Expression.Constant(id, typeof(TKey))), param); 

    return dataContext.GetTable<TEntity>().Single(lambda); 
} 
+0

LINQ to SQLのあまり知られていない機能(ランタイムメタデータ)を指摘しているので、これは間違いなく最良のアプローチであり、しかも良い答えです。 –

関連する問題