Entity Framework 6.X and one-to-one relationship

為{幸葍}努か 提交于 2019-12-11 06:29:33

问题


I have the following model:

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; }
    ......
}

and the following mapping:

        this.HasOptional(c => c.Driver)
            .WithOptionalPrincipal(a => a.AspNetUser)
            .Map(m => m.MapKey("AspNetUserId"));

It creates correct DB model, adds nullable AspNetUserId FK to Driver table.

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 :

"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."

How to solve it with EF 6.X ?


回答1:


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.

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();


来源:https://stackoverflow.com/questions/51710270/entity-framework-6-x-and-one-to-one-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!