EF 一对一关系在每次调用 SaveChanges() 时创建新记录

EF One to One relationship creates new record each on each call to `SaveChanges()`

我有一个 EF 模型,它强制执行 user > address 一对一的关系,经过精简后如下所示:

public class User 
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int AddressId { get; set; }
  [ForeignKey(nameof(AddressId))]
  public Address Address { get; set; } = new Address();
}

public class Address 
{
  public int Id { get; set; }
}

我使用的是通用存储库模式,但如果我直接在 EF 上下文中工作,也会发生同样的事情。

如果我这样做:

public void Create() 
{
  var user = new User();
  context.Users.Add(user);
  context.SaveChanges();
}

我在我的数据库中创建了一个附加了 address 的用户,AddressIdAddress.Id 属性 都设置为正确的值。

但是如果我这样做:

public void Update(int userId, String name) 
{  
  var user = context.Users.Single(x => x.Id == userId);
  user.Name = name;
  context.SaveChanges();
}

当我在 SaveChanges() 之后查看用户时,名称按预期更新但我在数据库中创建了一个全新的 Address 记录并且 EF 增加了 AddressId 属性 为用户新 Address.Id.

这似乎是我在架构定义或我期望的工作方式方面犯了一个基本错误。

任何人都可以阐明这一点吗?感谢任何想法。

编辑

如果我将 User 上的 AddressId 设为可为 null 的 int,然后像这样调整创建方法:

public void Create() 
{
  var user = new User();
  var address = new Address()
  context.Addresses.Add(address);
  user.Address = address;
  context.Users.Add(user);
  context.SaveChanges();
}

然后一切如我所料。

我认为这一行的问题是:public Address Address { get; set; } = new Address() - 每次,当 EF 从数据库中检索 User 时,它会将旧的 Address 重写为 全新的 一个,这就是 AddressId 被更改和递增的原因。因此,只需删除 new Address(),EF 将自行完成所有工作:

public class User 
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int AddressId { get; set; }
    //[ForeignKey(nameof(AddressId))] is redundant
    public virtual Address Address { get; set; }// = new Address();
}

public class Address 
{
    public int Id { get; set; }

    public virtual ICollection<User> Users {get;set;}
    public virtual ICollection<Organization> Organizations {get;set;}
}

使用不可为空 AddressId:

public void Create() 
{
    var address = new Address()
    context.Addresses.Add(address);
    context.SaveChanges();

    var user = new User{ AddressId = address.Id };
    context.Users.Add(user);
    context.SaveChanges();
}