Entity Framework 代码首先从父项中删除 zero/one 个子项

Entity Framework Code First deleting one to zero/one child from parent

我首先在代码内部创建了一个简单的 zero/one 关系。下面的代码的工作原理是我可以拥有一个 Person 实例,并且可以选择拥有一个 Account 及其在数据库中的模型。

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Account Account { get; set; }
}

public class Account
{
    public int Id { get; set; }
    public string Location { get; set; }
    public virtual Person Owner { get; set; }
}
//Mapping
modelBuilder.Entity<Person>().HasOptional(x => x.Account).WithRequired(x => x.Owner);

我想做的是能够从父项中删除可选的子项。我希望这能奏效。

using (Context ctx = new Context())
{
    var personToDeleteFrom = ctx.Persons.Single(x => x.Id == <personid>);
    personToDeleteFrom.Account = null;
    ctx.SaveChanges();
}

但是,关系的子对象只是留在数据库中。有没有办法使这项工作?如果不是,处理这种关系的最佳做法是什么?

您实际上并没有通过将导航 属性 设置为空来删除子数据。您需要实际删除数据才能让它消失。

只需将 Accounts 集合中的 null 设置更改为 Remove

using (Context ctx = new Context())
{
    var personToDeleteFrom = ctx.Persons.Single(x => x.Id == <personid>);
    ctx.Accounts.Remove(personToDeleteFrom.Account);
    ctx.SaveChanges();
}

这将删除 Account

这是由于 Entity Framework 处理 1:1 关系的行为。 EF 实际上并没有在数据库中添加外键字段,因为它们是不必要的。相反,它只是维护 Account 的主键始终等于关联的 Person.

的主键的关系

如果您尝试执行以下操作,您会看到出现此行为。

using (Context ctx = new Context())
{
    var person = ctx.Persons.Single(x => x.Id == <personid>);
    person.Account = null;
    ctx.SaveChanges();

    person.Account = new Account();
    ctx.SaveChanges();
}

这将抛出一个 System.Date.Core.Entity.UpdateException,因为它试图向帐户 table 添加一个条目,主键设置为 ,而主键已经存在。

因此,取消导航 属性 实际上并没有做任何事情。通过使每个实体的主键保持同步来维护这种关系。要真正删除帐户,您需要将其从 table 中删除。