Entity Framework 6.X 和一对一的关系
Entity Framework 6.X and one-to-one relationship
我有以下型号:
public partial class Driver
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Nickname { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
......
}
public partial class AspNetUser
{
public string Id { get; set; }
public string UserName { get; set; }
public virtual Driver Driver { get; set; }
......
}
和以下映射:
this.HasOptional(c => c.Driver)
.WithOptionalPrincipal(a => a.AspNetUser)
.Map(m => m.MapKey("AspNetUserId"));
它创建了正确的数据库模型,将可为空的 AspNetUserId FK 添加到驱动程序 table。
但是如何在代码中 link 一个对象与另一个对象。我没有 AspNetUserId 属性,所以,我尝试设置对象,如下所示:
_db.Drivers.Attach(driver);
_db.AspNetUsers.Attach(aspNetUser);
driver.AspNetUser = aspNetUser;
_db.SaveChanges();
但后来我遇到了一个例外:
"An error occurred while saving entities that do not expose foreign
key properties for their relationships. The EntityEntries property
will return null because a single entity cannot be identified as the
source of the exception. Handling of exceptions while saving can be
made easier by exposing foreign key properties in your entity types.
See the InnerException for details."
"Store update, insert, or delete statement affected an unexpected
number of rows (0). Entities may have been modified or deleted since
entities were loaded. See
http://go.microsoft.com/fwlink/?LinkId=472540 for information on
understanding and handling optimistic concurrency exceptions."
如何用EF解决 6.X ?
当 Driver
已经与 AspNetUser
相关联时,就会发生这种情况。当您附加 driver
且 AspNetUser
属性 为 null
时,EF 假定 AspNetUserId
的原始值为 null
并生成更新语句 AspNetUserId IS NULL
附加条件,当然与现有记录不匹配,命令 returns 0 条记录受影响,EF 生成相关异常。
解决方法是(1)在设置新值之前从数据库中加载原始Driver.AspNetUser
属性值。此外,为了正确处理新的 AspNetUser
已经与不同的 Driver
相关联的情况,您应该 (2) 加载 AspNetUser.Driver
属性:
_db.Drivers.Attach(driver);
_db.AspNetUsers.Attach(aspNetUser);
_db.Entry(driver).Reference(e => e.AspNetUser).Load(); // (1)
_db.Entry(aspNetUser).Reference(e => e.Driver).Load(); // (2)
driver.AspNetUser = aspNetUser;
_db.SaveChanges();
我有以下型号:
public partial class Driver
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Nickname { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
......
}
public partial class AspNetUser
{
public string Id { get; set; }
public string UserName { get; set; }
public virtual Driver Driver { get; set; }
......
}
和以下映射:
this.HasOptional(c => c.Driver)
.WithOptionalPrincipal(a => a.AspNetUser)
.Map(m => m.MapKey("AspNetUserId"));
它创建了正确的数据库模型,将可为空的 AspNetUserId FK 添加到驱动程序 table。
但是如何在代码中 link 一个对象与另一个对象。我没有 AspNetUserId 属性,所以,我尝试设置对象,如下所示:
_db.Drivers.Attach(driver);
_db.AspNetUsers.Attach(aspNetUser);
driver.AspNetUser = aspNetUser;
_db.SaveChanges();
但后来我遇到了一个例外:
"An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details."
"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions."
如何用EF解决 6.X ?
当 Driver
已经与 AspNetUser
相关联时,就会发生这种情况。当您附加 driver
且 AspNetUser
属性 为 null
时,EF 假定 AspNetUserId
的原始值为 null
并生成更新语句 AspNetUserId IS NULL
附加条件,当然与现有记录不匹配,命令 returns 0 条记录受影响,EF 生成相关异常。
解决方法是(1)在设置新值之前从数据库中加载原始Driver.AspNetUser
属性值。此外,为了正确处理新的 AspNetUser
已经与不同的 Driver
相关联的情况,您应该 (2) 加载 AspNetUser.Driver
属性:
_db.Drivers.Attach(driver);
_db.AspNetUsers.Attach(aspNetUser);
_db.Entry(driver).Reference(e => e.AspNetUser).Load(); // (1)
_db.Entry(aspNetUser).Reference(e => e.Driver).Load(); // (2)
driver.AspNetUser = aspNetUser;
_db.SaveChanges();