EF 6.1试图建立递归关系的错误-自引用表和FluentAPI

本文关键字:错误 自引用 FluentAPI 关系 递归 建立 EF | 更新日期: 2023-09-27 18:21:18

我在实体框架6.1中创建递归关系时遇到了很大的问题。

我需要一些不同类型的Categories,但已经为它们创建了一个"基本"抽象类。我使用的是"按类型表"分层策略。一个类别可能有ParentCategory,也可能没有。(如果不是,则为顶级类别)

在下面的代码中,我展示了如何创建抽象Category类以及ParentCategory和ChildCategories导航属性。我已经使ParentCategoryId可以为null,因为在顶级类别的情况下不需要它。我看到了一些帖子,这正是我在这里努力实现的目标,尽管我认为我已经解决了所有问题,但我仍然会遇到以下错误:

Category_ParentCategory::多重性与关系"Category_Parent Category"中的角色"Category_ ParentCategory_Target"中的引用约束冲突。由于Dependent Role中的所有属性都不可为null,因此Principal Role的多重性必须为"1"

我想知道这是否与Category是一个抽象类和我正在使用的添加继承模型有关,因为我在任何其他关于这种递归关系的帖子中都没有看到这种确切的用法。感谢您的帮助!

public abstract class Category : ICategory
{
    protected Category()
    {           
        ChildCategories = new HashSet<Category>();
    }
    public int CategoryId { get; private set; }
    public int? ParentCategoryId { get; set; }
    public virtual Category ParentCategory { get; set; }
    public virtual ICollection<Category> ChildCategories { get; set; }
}

public class WLCategory : Category, IWLCategory
{
    public WLCategory() : base()
    {
        DynamicFields = new HashSet<DynamicFieldDef>();
    }
    public virtual ICollection<DynamicFieldDef> DynamicFields { get; set; } 
}

使用FluentAPI,我将数据库创建配置为:

class CategoriesConfig : EntityTypeConfiguration<Category>
{
    public CategoriesConfig()
    {          
        HasOptional(p => p.ParentCategory).WithMany(p => p.ChildCategories)
            .HasForeignKey(p => p.ParentCategoryId);
        ToTable("Categories");
    }
}

class WLCategoriesConfig : EntityTypeConfiguration<WLCategory>
{
    public WLCategoriesConfig()
    {
        HasKey(p => p.CategoryId);
        ToTable("WLCategories");
    }
}

EF 6.1试图建立递归关系的错误-自引用表和FluentAPI

好的,找到问题了!在我的OnModelCreating方法中,我设置了一些全局配置,其中之一是:

 modelBuilder.Properties().Configure(p => p.IsRequired());

我想在默认情况下将所有属性设置为不可为null,除非我在逐个类的基础上显式重写属性。然而,我不认为这个全局设置会应用于以下数据类型:

int? (nullable int)

显然,我错了。(不知道为什么EF会试图让一个可以为null的int在DB中不可以为null,即使开发人员全局设置了IsRequired。int?的固有含义是"可以为null"。)我不得不在HasOptional语句之前向我的CategoriesConfig类显式添加以下代码行:

 Property(p => p.ParentCategoryId).IsOptional();

现在,一切都很好。:-)