2012-04-09 6 views
7

私は基本的に同じオブジェクトを異なる2つの同様のメソッドを持っています。 可能であれば、ジェネリックメソッドを作成する最良の方法は何ですか?類似した2つの異なるメソッドから汎用メソッドを作成するにはどうすればよいですか?

二つのオブジェクト:

public class StoreObject { 
    int Key; 
    string Address; 
    string Country; 
    int Latitude; 
    int Longitude; 
} 

public class ProjectObject { 
    int ProjectKey; 
    string Address; 
    string Description; 
} 

私は潜在的に汎用的にしたい二つの方法:

public StoreObject GetStoreByKey(int key) 
{ 
    using (DBEntities dbe = new DBEntities()) 
    { 
    StoreObject so = new StoreObject(); 
    var storeObject = (from s in dbe.StoreTables 
         where s.Key == key 
         select s).First(); 

    so.Key = storeObject.key; 
    so.Address = storeObject.address; 
    so.Country = storeObject.country; 
    so.Latitude = storeObject.latitude; 
    so.Longitude = storeObject.longitude; 

    return so; 
    } 
} 

public ProjectObject GetProjectByKey(int projectKey) 
{ 
    using (DBEntities dbe = new DBEntities()) 
    { 
    ProjectObject po = new ProjectObject(); 
    var projectObject = (from p in dbe.ProjectTables 
         where p.ProjectKey == projectKey 
         select p).First(); 

    po.Key = projectObject.p_key; 
    po.Address = projectObject.p_address; 
    po.Description = projectObject.p_description; 

    return po; 
    } 
} 

私はそれを注意する必要があります。
- 私はを制御することはできませんテーブルフィールドの名前付け方法(例:p_description)。
- DB内のStoreTableは、電話、郵便番号などの他のプロパティを持つ場合がありますが、コードに表示されている内容を表示することにのみ関心があります。
- ProjectTableでも同じです。

+1

。ほとんどすべての行が異なります。 where節としてExpressionを渡すこともできますが、それは事態をより複雑にするだけです。それらのメソッドのそれぞれは、扱うオブジェクトをどのように扱うかを正確に認識しています。私はそれが得られるほど多く抽象化されていると思う。 –

+0

私は類似点があると主張する必要があります。私はそれがすでに抽象化されていることに同意しますが、他の人々がそれをもっともっとそうする考えを持っているかもしれないかと尋ねてみます。 – kei

答えて

3

あなたのエンティティは異なるプロパティを持つので、ジェネリックを使用して1つのメソッド内のさまざまなプロパティに値を設定することは価値がありません。しかし、オブジェクト全体を返すだけで、興味のあるプロパティを使用することができます。

あなたは、基本的に各メソッドに2つの異なる機能してい
public T GetEntityByKey<T>(int key) 
{ 
    using (DBEntities dbe = new DBEntities()) 
    { 
    return = dbe.StoreTables.Set<T>.Find(new object[] {key}); 
    } 
} 

そして

StoreObject so = GetEntityByKey<StoreObject>(123); 
if(so != null) 
{ 
    int lat = so.Latitude; 
} 
+0

皆さんのご意見をいただきありがとうございますが、私はこの件についてスティーブの答えを求めなければなりません。 (私はStoreTablesからのものだけではないので、いくつかのものを変更する必要があります) – kei

2

返された型を実際に抽象化して、usingを因数分解することができますが、残りの部分については、要求された型のスイッチか、パラメータとして取得するフィールドと、つかいます。

前者は悪い習慣であり、方程式にはほとんど影響を与えません。後者は高価であり、乱雑になります。

このような外観のメソッドがたくさんある場合を除き、これは実際にはジェネリックのための良い候補ではありません。

HTH、

Bab。

+0

私は反射を考えましたが、これをジェネリックとして行うことが可能かどうかを確かめようと考えていました。 – kei

2

これは皆さんの「作業単位」全体ではないので、これらの方法のそれぞれで新鮮なDBEntities()コンテキストを使用することはおそらく問題の根本でしょう。

単一のWebリクエスト(またはアプリケーションにある他のリクエスト単位)のインスタンスを含むRepositoryクラスを作成し、これらのメソッドを含むクラスを作成すると、重複を排除するより良い方法になりますここにコードしてください。 using()の範囲は、これらの方法の外にあり、うまくいけばあなたのWebリクエストまたは他の時間単位に結びついています。

新しいクラスを作成する代わりに、DBEntities部分クラスを拡張して、これらのメソッドを組み込むこともできます(生成コードを前提とします)。

+0

良いアイデアだが、私はまだこれをジェネリックに変えようとしている。 – kei

2

それを使用する:別の型へ

  1. クエリをエンティティのエンティティ
  2. 地図

Th最初の部分はSteve Malloryによって対処されました。

マッパーフレームワークを使用して、あるインスタンスから別のインスタンスへの値のコピーを処理できます。各タイプの名前が一致しないので、名前をマップする方法(あなたの例では、 "p_"を追加して小文字にする方法)を伝える必要があります。 1つの可能性はEmit Mapperです。

あなたはは、すべての共通性をくくり出すためにた場合、それはのようになります。これらの方法は似ていない

public TResult GetById<TResult, TEntity>(int id) 
{ 
    using (DBEntities dbe = new DBEntities())  
    {   
     T result = dbe.StoreTables.Set<T>.Find(new object[] {key}); 
     var mapper = ObjectMapperManager.DefaultInstance 
      .GetMapper<TEntity, TResult>(
       new DefaultMapConfig().MatchMembers((m1, m2) => "p_" + m1.ToLower() == m2)); 

     return mapper.Map(result);  
    } 
} 
+0

Hmmm ..これを考慮しますが、3つのフィールドを手動でマッピングするほうが簡単かもしれません。 – kei

関連する問題