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;
}

私が潜在的にジェネリックにしたい2つの方法:

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についても同じことが言えます。

4

4 に答える 4

3

トリッキーな部分は、エンティティがさまざまなプロパティを持っていることです。そのため、ジェネリックを使用して1つのメソッド内でさまざまなプロパティを設定する価値はありません。ただし、オブジェクト全体を返し、目的のプロパティを使用することもできます。

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;
} 
于 2012-04-10T00:53:21.000 に答える
2

返される型を抽象化し、因数分解することはできusingますが、それ以外の場合は、要求された型のスイッチをオンにするか、フィールドに渡してパラメーターとして取得するリフレクションと、使用するDBクエリのいずれかが必要です。

前者は悪い習慣であり、方程式にほとんど影響を与えません。後者はコストがかかり、厄介になる可能性があります。

このような類似したメソッドが多数ある場合を除いて、これはジェネリックスの候補としてはあまり適していません。その場合は、リフレクションアプローチを使用します。

HTH、

バブ。

于 2012-04-10T00:08:55.607 に答える
2

これが「作業単位」全体である可能性は非常に低いため、DBEntities()これらの各メソッドで新しいコンテキストを使用することが、ここでの問題の根本である可能性があります。

単一のWebリクエスト(またはアプリケーションにある他のリクエストユニット)Repositoryのクラスのインスタンスを含み、これらのメソッドを含むクラスを作成することは、ここで重複するコードを排除するためのより良いアプローチです。DBEntitiesその場合、の範囲はusing()これらのメソッドの範囲外になり、できればWebリクエストまたは他の時間単位に関連付けられます。

オプションとして、新しいクラスを作成する代わりに、DBEntities部分クラスを拡張して、これらのようなメソッドを含めることもできます(これが生成されたコードであると想定しています)。

于 2012-04-10T00:11:50.407 に答える
2

基本的に、各メソッドには2つの異なる機能があります。

  1. エンティティをクエリする
  2. そのエンティティを別のタイプにマップします

最初の部分はスティーブマロリーによって扱われました。

2番目の部分では、マッパーフレームワークを使用して、あるインスタンスから別のインスタンスへの値のコピーを処理できます。各タイプの名前は一致しないため、名前をマップする方法を指定する必要があります(この例では、「p_」を追加して小文字にします)。1つの可能性はEmitMapperです。

すべて共通点を除外すると、次のようになります。

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);      
    }
}
于 2012-04-10T01:24:15.647 に答える