Entity Framework中的自引用/父子关系

31

我阅读了很多程序员的帖子,他们在使用Entity Framework中的自引用关系时遇到了无法确定依赖操作的有效排序。由于外键约束、模型要求或存储生成的值可能存在依赖关系-异常。

我正在尝试使父子关系正常工作:

public class Category {
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public Category Parent { get; set; }
    public List<Category> Children { get; set; }
}

这是我使用的配置(Fluent API):

Property(c => c.ParentId).IsOptional();
HasMany(c => c.Children).WithOptional(c => c.Parent).HasForeignKey(c => c.ParentId);
//HasOptional(c => c.Parent).WithMany(c => c.Children).HasForeignKey(c => c.ParentId);

当我尝试像这样保存新类别时,HasMany() 和 HasOptional() 配置都会导致 "无法确定依赖操作的有效排序..." 异常:

context.Categories.Add(new Category { Name = "test" });

我不明白为什么EF不会插入具有空的parentId的Category。数据库允许ParentId外键为空。

您能告诉我如何做吗?

2个回答

35

要将属性ParentId用作可选关系的外键属性,必须将其定义为类别类中的可空类型:

public int? ParentId { get; set; }

int属性无法接受值null,因此不能在数据库列中将其表示为NULL值。


1
有没有一种方法可以使用属性(流畅)实现这种父子关系? - Shimmy Weitzhandler

1

由于有人在评论中询问如何使用属性进行此操作。您还可以利用数据注释来设置它。使用与上面相同的示例:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class Category {
    // You can also add [DatabaseGenerated(DatabaseGeneratedOption.Identity)]  
    // as an attribute, if this field is to be generated by the database
    [Key] // Define this as the primary key for the table
    public int CategoryId { get; set; }
    public string Name { get; set; }

    [ForeignKey(nameof(Parent))]  // Link the Parent object to the ParentId Foreign Key
    public int? ParentId { get; set; }
    public Category Parent { get; set; }

    public List<Category> Children { get; set; }
}

这在 EF 6 中经过测试并且可行。


非常感谢您抽出时间来记录和测试注释的方法! - Phil Nicholas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接