動態地在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。然後在同一個程序集中的其他地方,我用這種方式:

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

此時, model包含InternalDbSet<ModelA>類型的實例。從那裡,我對model對象的任何使用我得到一個RunTimeBinderException:'Microsoft.Data.Entity.Internal.InternalDbSet'不包含'FirstOrDefault'的定義

在網上調查,我找到了一篇博客文章解釋說(dixit他的博客):

調用FirstOrDefault()失敗的原因是模型的類型信息在運行時不可用。它不可用的原因是因為匿名類型不公開。當該方法返回該匿名類型的實例時,它返回一個System.Object,它引用一個匿名類型的實例 - 一個類型,其信息不可用於主程序。

然後他指出了一個解決方案:

解決方案實際上非常簡單。我們所要做的就是打開ClassLibrary1項目的AssemplyInfo.cs並向其添加以下行: [assembly:InternalsVisibleTo("assembly-name")]

我確實在我的代碼上嘗試了這個解決方案,但它不起作用。有關信息,我有一個asp.net 5解決方案,在dnx dotnet46上運行兩個程序集。一個app和一個包含我所有模型和DbContext的dll。我所做的所有相關電話都位於dll上。

這個解決方案有沒有機會工作?我錯過了什麼嗎?任何指針都會非常感激?

提前致謝

[編輯]

我試圖返回IQueryable<dynamic>而不是dynamic ,我可以做基本的查詢模型model.FirstOrDefault(); 最重要的是我也希望能夠過濾一個字段:

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

熱門答案

那麼當我在編譯期間不知道<T>時,我是怎麼做到的。

首先需要獲取類型為DbContext.Set方法返回一個非泛型DbSet實例,以訪問上下文和底層存儲中給定類型的實體。

public virtual DbSet Set(Type entityType)

注意這裡參數是應該返回一個集合的實體的類型。為給定的實體類型設置的是返回值。

public virtual DbSet Set(Type entityType)

現在我有這種類型

public virtual DbSet Set(Type entityType)

或者是一個班輪

public virtual DbSet Set(Type entityType)



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因