EF One to One关系在每次调用“SaveChanges()”

时间:2017-09-22 13:14:15

标签: asp.net-mvc entity-framework entity-framework-6 one-to-one

我有一个强制user>的EF模型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()名称按预期更新后查看用户时,我在DB中创建了一个全新的Address记录,并且EF增加了AddressId属性用户使用新的Address.Id

这似乎是我在架构定义中或者我希望事情如何发挥作用时发生的基本错误。

任何人都可以对此有所了解吗?感谢任何想法。

修改

如果我在AddressId上设置User一个可以为空的int,然后像这样调整create方法:

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

然后事情就像我期待的那样起作用。

1 个答案:

答案 0 :(得分:2)

我认为这一行的问题是:public Address Address { get; set; } = new Address() - 每当EF从数据库中检索User时,它会将旧的Address重写为全新的 ,这就是为什么AddressId被改变和icremented。因此,只需删除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();
}