EF1:文字列値を渡すことにより、.oftype <>を使用して派生派生タイプのエンティティクラスをフィルタリングする

StackOverflow https://stackoverflow.com/questions/4746409

質問

派生サブクラスを使用してlinqセレクトをフィルタリングしようとしている状況があります。

ctx.BaseEntity.OfType<SubClass>() - これは正常に機能します。

ただし、代わりに文字列値を使用してこれを行いたいと思います。私は多くの(> 20)サブクラスを持っているときにパフォーマンスの障壁に出くわし、OFTYPEを使用せずにエンティティを選択することはオプションではありません。基本クラスからレンダリングする一般的なUIがあるので、コンパイル時にどのクラスのタイプが返されるかわかりません。

だから私がやりたいのはこれです:

  1. データベースからサブクラスストタイプのみを返す場所で投影された選択を実行します
  2. OFTYPEとしてこの値を使用して2番目の選択を実行して、データベースから関連する関連エンティティのみを選択します(大衆ユニオンが生成されません)

        int id = 1;
        var classType = (from c in ctx.BaseClass.Include("ClassType")
                                   where c.id == id
                                   select new
                                              {
                                                  c.ClassType.TypeName
                                              }).First();
    
        BaseClass caseQuery = ctx.BaseClass.OfType<classType.TypeName>()
                        .Include("ClassType")
                        .Include("ChildEntity1")
                        .Include("ChildEntity2")
                        .Where(x => x.id== id);
    

しかし、Oftypeには文字列ではなくタイプが必要であるため、これは明らかに機能しません。

これを達成する方法についてのアイデアはありますか?

アップデート:元の質問へのサイドノートとして、ナビゲーションプロパティを使用するクエリを投影する瞬間、モンスターSQLも構築します。そのため、ベースクラスからのclasStypeエンティティを格納するためにストアドプロシージャを使用することになりました。 ID。

役に立ちましたか?

解決

ですから、ESQLを使用して動作するようになったばかりです。誰かを助ける場合に備えて、ここにコードを投稿しました。他の誰かが、彼らが考えることができるより強くタイプされたソリューションを手に入れましたか?

BaseClass caseQuery = ctx.BaseClass.CreateQuery<BaseClass>("SELECT VALUE c FROM OFTYPE(Entities.[BaseClass],namespace.[" + classType.TypeName + "])  as c")
                .Include("ClassType")
                .Include("ChildEntity1")
                .Include("ChildEntity2")
                .Where(x => x.id== id).FirstOrDefault();

他のヒント

呼び出しに関する見出しの質問に答える OfType 文字列 /ランタイムタイプを使用すると、次のことを行うことができます。

// Get the type, assuming the derived type is defined in the same assembly 
// as the base class and you have the type name as a string
var typeToFilter = typeof(BaseClass)
     .Assembly
     .GetType("Namespace." + derivedTypeName);

// The use reflection to get the OfType method and call it directly
MethodInfo ofType = typeof(Queryable).GetMethod("OfType");
MethodInfo ofTypeGeneric = method.MakeGenericMethod(new Type[] { typeToFilter });
var result = (IQueryable<Equipment>)generic.Invoke(null, new object[] { equipment });

これをストアドプロシージャと組み合わせてクラス名を取得し、大規模な結合を避ける必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top