DbContext内の汎用DbSetを動的に検索する

.net asp.net-mvc-5 c# entity-framework-core

質問

私はこの質問が既に尋ねられていることを知っていますが、私は私を満足させる答えを見つけることができませんでした。私がしようとしているのは、その型の名前に基づいて特定のDbSet<T>を取得することです。

私には次のものがあります:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyDllAssemblyName")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyCallingAssemblyName")]

class MyDbContext : DbContext {

    public DbSet<ModelA> A { get; set; }
    public DbSet<ModelB> B { get; set; }

    public dynamic GetByName_SwitchTest(string name) {
        switch (name) {
            case "A": return A;
            case "B": return B;
        }
    }

    public dynamic GetByName_ReflectionTest(string fullname)
    {
        Type targetType = Type.GetType(fullname);
        var model = GetType()
            .GetRuntimeProperties()
            .Where(o => 
                o.PropertyType.IsGenericType &&
                o.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>) &&
                o.PropertyType.GenericTypeArguments.Contains(targetType))
            .FirstOrDefault();
        if (null != model)
            return model.GetValue(this);
        return null;
    }
}

簡単なスイッチか反射かにかかわらず、タイプ自体を取得するのに問題はありません。私はDbSetの型がわからないので、型を動的として返す必要があります。次に、同じアセンブリのどこか他の場所で、私はこの方法で使用します。

// MyDbContext MyDbContextInstance..
var model = MyDbContextInstance.GetByName_SwitchTest("A");
var record1 = model.FirstOrDefault(); // It crashes here with RunTimeBinderException

この時点で、 modelInternalDbSet<ModelA>型のインスタンスが含まれています。そこから、私はRunTimeBinderExceptionを取得するmodelオブジェクトを使用する: 'Microsoft.Data.Entity.Internal.InternalDbSet'には 'FirstOrDefault'の定義が含まれていません

ウェブ上で調査すると、私はそのブログの投稿を見つけました(彼のブログをdixit):

FirstOrDefault()の呼び出しが失敗する理由は、モデルの型情報が実行時に利用できないということです。それが利用できない理由は、匿名型が公開されていないためです。メソッドがその匿名型のインスタンスを返すとき、匿名型のインスタンスを参照するSystem.Objectを返します。これは、情報がメインプログラムで利用できない型です。

そして、彼はその解決策を指摘する。

解決策は実際には非常に簡単です。私たちがしなければならないことは、ClassLibrary1プロジェクトのAssemplyInfo.csを開き、それに次の行を追加することです: [assembly:InternalsVisibleTo("assembly-name")]

私は自分のコードでこの解決策を試しましたが、うまくいきません。私は、dnx dotnet46上で動作する2つのアセンブリを持つasp.net 5ソリューションを持っています。私のすべてのモデルとDbContextを含むappとdll。私が行うすべての懸念されている呼び出しはdllにあります。

このソリューションには何らかの機会がありますか?何か不足していますか?すべてのポインタは非常に高く評価されるだろうか?

前もって感謝します

[編集]

私は返すようにしようとしたIQueryable<dynamic>するのではなくdynamicと私は基本的なクエリを行うことができますmodel.FirstOrDefault(); しかし、とりわけ私はフィールド上でフィルタリングすることができるようにしたい:

var record = model.FirstOrDefault(item => item.MyProperty == true);

人気のある回答

コンパイル時に<T>認識していないときはどうしましたか?

まず、 DbContext.Setメソッドは、コンテキスト内の指定された型のエンティティおよびその基底のストアにアクセスするための汎用でないDbSetインスタンスを返します。

public virtual DbSet Set(Type entityType)

ここで、引数は、セットが返されるべきエンティティの型であることに注意してください。指定されたエンティティタイプに対して返される値は戻り値です。

var type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.Name == <Pass your table name>);

今私はこのタイプがある

if(type != null)
{
DbSet context = context.Set(type);
}

または1つのライナーは

DbSet mySet = context.Set(Type.GetType("<Your Entity Name>"));


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ