MVC一对多数据库未更新

时间:2015-11-28 20:53:21

标签: asp.net asp.net-mvc entity-framework

我在我的MVC项目中添加了ApplicationCompany类,如下所示:

public class ApplicationCompany
{
    public Guid Id { get; set; }
    public String Name { get; set; }

    public virtual List<ApplicationUser> Users { get; set; }

    public ApplicationCompany()
    {
        Id = Guid.NewGuid();
        Users = new List<ApplicationUser>();
    }
}

在我添加的ApplicationUser课程中:

public virtual ApplicationCompany Company { get; set; }

现在,当我调试ApplicationUser的实例时,我可以看到它具有Company属性,我可以在数据库中看到ApplicationCompany表。当用户注册时,我想添加一个Company链接到他们。我正在做以下事情,但它没有挽救公司:

using (var context = new ApplicationDbContext())
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationManager
        {
            UserName = model.Email,
            Email = model.Email
        };

        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            var company = new ApplicationCompany();
            user.Company = company;
            context.SaveChanges();
            ...
        }
    }
}

任何想法为什么?

2 个答案:

答案 0 :(得分:1)

您在DbContext块中使用的if (result.Succeeded)实例在调用user之前,对您刚设置的context.SaveChanges()实例一无所知。通过将user实例附加到上下文中或仅将user的状态更改为EntityState.Modified来修改代码。

if (result.Succeeded)
{
    var company = new ApplicationCompany();
    user.Company = company;
    context.Entry(user).State = EntityState.Modified;
    context.Entry(company).State = EntityState.Added;
    context.SaveChanges();
}

修改1:

  

附加类型&#39; ApplicationUser&#39;的实体失败,因为同一类型的另一个实体已具有相同的主键值

由于另一个上下文拥有用户实例,因此您必须将DbContext实例化到if块中(不要忘记取消在方法开头创建的根实例)像这样:

if (result.Succeeded)
{
    using (var context = new ApplicationDbContext())
    {
        var company = new ApplicationCompany();
        user.Company = company;
        context.Entry(user).State = EntityState.Modified;
        context.Entry(company).State = EntityState.Added;
        context.SaveChanges();
    }
}

编辑2:覆盖CreateAsync课程中的ApplicationUserManager方法

更好的方法,恕我直言,是CreateAsync课程中的ApplicationUserManager方法。通过这样做,您不需要将公司更新添加到您的控制器的操作中。

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    // ...

    public override async Task<IdentityResult> CreateAsync(ApplicationUser user, string password)
    {
        var company = new ApplicationCompany();
        user.Company = company;
        return await base.CreateAsync(user, password);
    }
}

答案 1 :(得分:0)

问题在于,您使用的是不同的DbContext对象来插入用户而不是用于插入公司的用户。您应该使用相同的DbContext对象。

更改您的UserManager.CreateAsync方法以接受DbContext对象并在那里使用它来添加新用户

public Task<SomeDTO> CreateAsync(ApplicationDbContext db, ApplicationUser user,
                                                                         string password)
{
  //to do  : Set the password

  //Use db to add the new User
  db.ApplicationUsers.Add(user);
  await db.SaveChangesAsync();
  // to do  : return something
}

当你从action方法调用它时,请确保传递DbContext。

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

那应该解决你的问题。