实体框架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添加到驱动程序表中.
It creates correct DB model, adds nullable AspNetUserId FK to Driver table.
但是如何在代码中将一个对象链接到另一个对象.我没有AspNetUserId属性,因此,我尝试设置对象,如下所示:
But how to link one object with another in code. I don't have AspNetUserId property, so, I try to set object, like this:
_db.Drivers.Attach(driver);
_db.AspNetUsers.Attach(aspNetUser);
driver.AspNetUser = aspNetUser;
_db.SaveChanges();
但随后我出现了一个异常:
but then I got an exception :
"保存不公开外部内容的实体时发生错误 关系的关键属性. EntityEntries属性 将返回null,因为无法将单个实体标识为 异常的来源.保存时处理异常可以是 通过在您的实体类型中公开外键属性,使操作变得更加容易. 有关详细信息,请参见InnerException."
"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."
存储更新,插入或删除语句影响了意外 行数(0).自从以来,实体可能已被修改或删除 实体已加载.看 http://go.microsoft.com/fwlink/?LinkId=472540 有关的信息 了解和处理乐观并发异常."
"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解决它?
How to solve it with EF 6.X ?
推荐答案
当Driver
已经与AspNetUser
关联时,就会发生这种情况.当您将driver
的AspNetUser
属性设置为null
时,EF假定AspNetUserId
的原始值是null
并生成带有AspNetUserId IS NULL
附加条件的更新语句,这当然与现有记录不匹配,该命令将返回0条受影响的记录,并且EF生成有问题的异常.
This is happening when the Driver
is already associated with AspNetUser
. When you attach the driver
with AspNetUser
property being null
, EF assumes the original value of AspNetUserId
being null
and generates update statement with AspNetUserId IS NULL
additional criteria, which of course does not match the existing record, the command returns 0 records affected and EF generates the exception in question.
解决方案是(1)在设置新值之前从数据库加载原始Driver.AspNetUser
属性值.另外,为了正确处理新的AspNetUser
已经与其他Driver
关联的情况,您还应该(2)加载AspNetUser.Driver
属性:
The solution is (1) to load the original Driver.AspNetUser
property value from the database before setting the new value. Also, in order to correctly handle the case when the new AspNetUser
is already associated with a different Driver
, you should (2) load AspNetUser.Driver
property as well:
_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();
这篇关于实体框架6.X与一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!