实体框架代码首先是一对一的,而不是一对多的

本文关键字:一对多 框架 一对一 实体 代码 | 更新日期: 2023-09-27 18:16:20

我完成了一个首先使用EF6代码的项目。我有两个类,其中一对多的关系设置,在Fluent API中设置相同。

当我在同一步骤中创建父/子时,一切都很好并保存了,但是当我首先创建父/子时,保存它,然后我想添加一个子,我得到一个异常,说明这两个实体的关系是1到0..1 .不保存。

是否有办法首先只创建父节点,然后添加子节点?

模型类:

public class Parent
{
    public int ParentId {get; set;}
    public virtual ICollection<Child> Children {get; set;}
}
public class Child
{
    public int ChildId {get; set;}
    public virtual Parent Parent {get; set;}
}

流利的API:

modelBuilder.Entity<Child>()
                     .HasRequired<Parent>(s => s.Parent)
                     .WithMany(s => s.Children)
                     .HasForeignKey(s => s.ParentId);

在数据库中,我看到外键ParentId。如果我是对的,没有孩子的父母也可以存在。使用dbContext.SaveChanges()

保存所有内容异常:

Exception thrown: 'System.Exception' in Project.dll
Additional information: Multiplicity constraint violated. The role 'Child_Parent_Target' of the relationship 'Project.DAL.Child_Parent' has multiplicity 1 or 0..1.

实体框架代码首先是一对一的,而不是一对多的

考虑给孩子一个ParentId属性

public class Child
{
    public int ChildId {get; set;}
    public int ParentId {get; set;}
    public virtual Parent Parent {get; set;}
}

如果这样做,则遵循代码优先约定(单击查看)。如果你遵循约定,实体框架理解父-子是一对多关系:父节点有零个或多个子节点,子节点只有一个父节点。

遵循约定的好处是你不需要流畅的API语句。实体框架知道父节点是必需的,父节点有许多子节点,并且父节点的外键是ParentId

回到你的问题上来。将ParentId添加到子节点后,您可以添加没有子节点的父节点,以后再添加子节点。

添加ParentId后,您可以添加父级,然后添加子级

public class Parent
{
    public int ParentId {get; set;}
    public string Name {get; set;}
    public virtual ICollection<Child> Children {get; set;}
}
public class Child
{
    public int ChildId {get; set;}
    public string Name {get; set;}
    // By convention will become the foreign key to Parent:
    public int ParentId {get; set;}
    public virtual Parent Parent {get; set;}
}
public class MyDbContext : DbContext
{
    public DbSet<Parent> Parents {get; set;}
    public DbSet<Child> Children {get; set;}
}
public void Main()
{
    using (var dbContext = new MyDbContext(...))
    {
        var addedParent = dbContext.Parents.Add(new Parent()
        {
             Name = "Phil Dunphy",
        }
        // if you do not want to add a child now, you can SaveChanges
        dbContext.SaveChanges();
        // now addedParent has a ParentId, you can add a child:
        var addedChild = dbContext.Children.Add(new Child()
        {
            Name = "Luke Dunphy",
            ParentId = addedParent.Id,
        };
        dbContext.SaveChanges();
    }
}