代码之家  ›  专栏  ›  技术社区  ›  user6111463

实体框架插入数据库中已存在的实体

  •  0
  • user6111463  · 技术社区  · 7 年前

    我使用的是EF 6 Code First MVC plus标识

    我自定义了Identity framework中定义的标准ApplicationUser类,当我尝试通过网页注册新用户时,EF尝试插入数据库中已经存在的实体。

    //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
    

    根据我得到的错误,听起来EF正在将Country实体插入db。我猜当EF向db添加地址时会发生这种情况。在我的代码中,Address是一个新对象,但City、State和Country已经存在了,您可以看到我一开始是从db加载City的。因此,我尝试使用以下代码,但没有任何帮助:

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

    很抱歉,代码太长了,但我尝试将其最小化。

    这是我的模型:

    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;
    }
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   FLICKER    7 年前

    我很久以前也有过类似的问题。我不知道问题出在哪里,但我有一个解决方法:

    替换代码:

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

    代码如下:

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

    这将正确保存数据。

        2
  •  0
  •   bilpor    7 年前

    问题是,您每次都在创建新对象。您需要首先执行测试,以查看用户是否存在,然后使用现有数据填充对象并使用更新。因此,您还需要考虑使用 UserManager.UpdateAsync 方法