簡體   English   中英

僅使用某些類的帶有POCO的實體框架6

[英]Entity Framework 6 with POCO Using Only Some Classes

我在另一個VS項目中使用了多個相互關聯的類,例如:

namespace MyOtherProject
{
    public class A {
        public string Name {get;set;}
    }

    public class B {
        public int Value {get;set;}
        public A Child {get;set;}
    }
}

現在,我想首先在EF中將這些類用作POCO用於代碼。 但是,我不需要數據庫中的所有類,而只需要其中一些。 所以我創建了一個上下文:

public class MyContext : DbContext
{
    public MyContext () : base("MyContext ")
    {
    }

    public DbSet<B> Bs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

當我嘗試運行項目時,出現此錯誤:

System.Data.Entity.ModelConfiguration.ModelValidationException:在模型生成期間檢測到一個或多個驗證錯誤:MyProject.A:名稱:模式中的每個類型名稱都必須是唯一的。 類型名稱“ A”已經定義。

請注意,錯誤中的名稱空間與類A的定義不同,因為我的類A是在另一個(共享)項目中定義的。 相反,名稱空間是上下文之一。

https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net上-mvc-application我讀到此:

您可能已經省略了DbSet和DbSet語句,它的工作原理相同。 實體框架將隱式包括它們,因為學生實體引用了注冊實體,而注冊實體引用了課程實體。

我的假設(未確認)是EF看到B引用了A但沒有類型A的數據集,因此它在內部生成了一個類A,然后突然發現有兩個此類。

任何人都知道確切的問題是什么,我該怎么做才能解決它? 我有太多我並不需要的類,所以我不想為我擁有的每個類創建數據集。

首先,從DbSet<Type1>獲取所有通用類型參數( Type1Type2 ...)。 然后,應檢查每種類型的內部屬性類型,即對其他類型的引用(作為直接鏈接或通過ICollection集),-如果此內部類型在第一個tableTypes集合中不存在,我們將忽略它們。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {         
        //other stuff.....

        Func<Type, bool> genericFilter = x => typeof(IEnumerable).IsAssignableFrom(x) && x.GenericTypeArguments.Length == 1;

        //All types of your context tables
        var tablesTypes = GetType().GetProperties()
            .Where(x => genericFilter(x.PropertyType))
            .Select(x => x.PropertyType.GenericTypeArguments.First());

        var namespaces2ignore = new List<string> { "Namespace2Ignore1", "Namespace2Ignore2" };
        var toIgnore = new List<Type>();
        foreach (var type in tablesTypes)
            //Ignore internal types, which not exist at tablesTypes
            toIgnore.AddRange(type.GetProperties()
                .Select(x => genericFilter(x.PropertyType) ? x.PropertyType.GenericTypeArguments.First() : x.PropertyType)
                .Where(x => !tablesTypes.Contains(x) && namespaces2ignore.Contains(x.Namespace)
                /*or as you suggested: && typeof(A).Assembly == x.Assembly*/
            ).ToList());            

        modelBuilder.Ignore(toIgnore);
    }

如果要在特定對類型屬性上添加條件,可以執行以下操作:

    foreach (var type in tablesTypes)
        foreach(var prop in type.GetProperties()
            .Select(x => new { type = genericFilter(x.PropertyType) ? x.PropertyType.GenericTypeArguments.First() : x.PropertyType, prop = x })
            .Where(x => !tablesTypes.Contains(x.type) && namespaces2ignore.Contains(x.type.Namespace)                
        ).ToList())
            if(!(type == typeof(TestType) && prop.prop.Name == "Test"))
                toIgnore.Add(prop.type);

現在將不會排除類型為TestType名稱為“ Test”的TestType

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM