2

Products1、Products2、Products3 など、構造的には同じであるが命名規則が異なる多数のエンティティ オブジェクトがあります (これは従来のデータベース スキーマの一部であり、これについてはあまりできません)。

これらのクラスは、CLR に関する限りさまざまなタイプであり、残念ながら設計コードが自動生成されるため、共通性を示すためにこれらのクラスにインターフェイスを平手打ちすることはできません。だから、私の質問は: エンティティ オブジェクトを名前で取得する方法はありますか?

これらのオブジェクトに本質的に同じロジックを適用するときは、基本的にスイッチ/ケース ビジネスを避けたいと思います。

4

3 に答える 3

2

式ツリーを構築して、問題のオブジェクトを照会できます。

public T GetSingleObject<T>(int someValue) {
    MyEntities db = new MyEntities();
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

    var param = Expression.Parameter(typeof(T));

    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(param, "WhateverPropertyYourComparing"),
            Expression.Constant(someValue)),
        param);

    return result.SingleOrDefault(lambda);
}

または、オブジェクトのコレクションが必要な場合

public IEnumerable<T> GetResultCollection<T>(int someValue) {
    MyEntities db = new MyEntities();
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

    var param = Expression.Parameter(typeof(T));

    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(param, "WhateverPropertyYourComparing"),
            Expression.Constant(someValue)),
        param);

    return result.Where(lambda);
}

もちろん、必要なクエリが非常に長い場合、これは手に負えなくなる可能性があり、Justin Morgan が提案したように、部分クラスを使用して必要なインターフェイスを追加することを検討する必要があります。

このメソッドは、ObjectSet コレクションがオブジェクトと同じ名前に「s」を加えたもの、つまり「Invoice」から「Invoices」であると想定していることに注意してください。そうでない場合、つまり「Person」から「People」の場合、System.Data.Entity.Design.PluralizationServices.PluralizationService を使用して適切な名前を取得できます。

于 2011-02-19T20:22:38.620 に答える
1

EF4 クラスは部分クラスであるため、実際にそれらを拡張し、選択したインターフェイスを実装させることができます。すべて別のファイルで行います。

その代わりにdynamic、エンティティをそのタイプに基づいてインスタンス化するだけです。

dynamic myEntity= Activator.CreateInstance(Type.GetType("EntityTypeHere")));
myEntity.CommonProperty = "Foo";

ここでの大きな欠点は、コンパイル時にすべての型の安全性が失われることです。問題は実行時にのみ発見され、静的に型付けされたアプローチよりも遅くなります。

于 2011-02-19T02:26:31.743 に答える
0

私たちが話しているクラスの数と、あなたがどれだけ柔軟である必要があるかによっては、インターフェースは問題外ではないかもしれません。私はジェネリックを使用して同様のことをしました:

//WARNING: Partially-remembered code ahead...
interface IDuckEntity
{
    int FeatherCount { get; set; }
}

public partial class Products1 : IDuckEntity { }
public partial class Products2 : IDuckEntity { }
public partial class Products3 : IDuckEntity { }

//in some other class:
void DoStuff<T>(T entity) where T : EntityObject, IDuckEntity
{
     entity.FeatherCount = 500;
}

したがって、基本的には、インターフェイスとそれらの小さな部分的なクラス宣言の束を配置する別のファイルを設定します。次に、共通の構造にアクセスできるようになります。あなたの正確な状況はわかりませんが、これは私にとって魅力のように機能しました。

于 2011-02-19T02:12:38.320 に答える