简体   繁体   中英

Entity Framework Inserts the entity Already Exists in Database

I'm using EF 6 Code-First MVC plus Identity

I have customized the standard ApplicationUser class defined in Identity framework and when I try to register a new user through my web page, EF tries to insert an entity which is already exists in database.

//some code above here

using (ApplicationDbContext db = new ApplicationDbContext())
{
    // I load the City object form db based on the model passed to current method
    City city = db.Countries.Include("States.Cities")
        .First(c => c.Code == model.CountryCode)
        .States.First(s => s.Id == model.StateId)
        .Cities.First(ci => ci.Name == model.CityName);

    // I create a new Employee and a new Company and Company has an Address 
    // referring to the City I loaded from db
    Employee employee = new Employee
    {
        FirstName = model.FirstName,
        LastName = model.LastName,
        Company = new Company
        {
            Name = model.CompanyName,
            OfficePhone = model.OfficePhone,
            Address = new Address { City = city, Street = model.Street, ZipCode = model.ZipCode }
        }
    };

    // This is part of Identity framework code
    var user = new ApplicationUser
    {
        UserName = model.Email,
        Email = model.Email,
        // my custom code: I assign employee to the standard ApplicationUser class
        UserProfile = employee
    };

    // This is going to save the new user to database, 
    // but it tries to insert a new Country object into db. 
    // Note that City class has a property of type State 
    // and State class has a property type of Country 
    var result = await UserManager.CreateAsync(user, model.Password);

    // more code below

Based on error I get, sounds like EF is inserting Country entity into db. I guess it happens when EF is adding Address to db. in my code, Address is new object but City, State and Country are already there and you see that I'm loading City from db in the beginning. So I tried using below code but it did not help:

db.Entry(employee.Company.Address.City).State = EntityState.Unchanged;

Sorry for lengthy code, I tried to minimize that though.

This is my model:

public class Country
{
    string Code;
    string Name;
    List<State> States;
}

public class State
{
    int Id;
    string Name;
    List<City> Cities;
}

public class City
{
    int Id;
    string Name;
    State State;
}

public class Address
{
    string Street;
    string ZipCode;
    City City;
}

public class Company
{
    string Name;
    string OfficePhone;
    Address Address;
}

The problem is, you are creating new objects each time. You need to perform a test first to see if the user exists, and if it does then populate the object with existing data and use Update. So you need to also think about using UserManager.UpdateAsync method.

I had similar problem long back. I don't know the problem but I have a workaround:

replace the code:

var result = await UserManager.CreateAsync(user, model.Password);

with below code:

var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
var result = UserManager.Create(user, model.Password);

This will save data correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM