如何使用EF6更新与ApplicationUser相关的实体?

时间:2017-09-06 00:59:18

标签: c# asp.net asp.net-mvc entity-framework design-patterns

我在ASP.NET MVC中更新与应用程序用户相关的实体时遇到问题。我在ApplicationUserOrder之间有一对多的关系。这是我的实体和关系配置:

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<Order> HandlingOrders { get; set; }
}

public class Order
{
    public int Id { get; set; }
    //some properties

    public string OperatorId { get; set; }
    [ForeignKey("OperatorId")]
    public virtual ApplicationUser Operator { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<ApplicationUser>().HasMany(n => n.HandlingOrders)
                                          .WithOptional(n => n.Operator)
                                          .HasForeignKey(n => n.OperatorId);
}

问题是,当我尝试在我的控制器中保存Order时,它失败并显示InvalidOperationException和消息

  

无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象。

这是因为我一方面使用“工作单元”和“通用存储库”来保存Order。另一方面,我使用ApplicationUserManager保存ApplicationUser

public class OperatorController : Controller
{
    private readonly UnitOfWork _unitOfWork;

    private ApplicationUserManager _userManager
    {
        get { return HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
    }
}

结果我得到两个上下文:第一个是来自IOwinContext的{​​{1}},第二个是我的常规GetOwinContext(),在“工作单位”中创建(或正在创建?)。而这种情况导致例外。

有人能建议我,在这种情况下最好的是什么?我为ApplicationContext编写存储库而奋斗,但我从未在文章中看到过这样的做法,所以我不确定。

1 个答案:

答案 0 :(得分:1)

第一种方式解释: 根据你的错误信息,据我所知,可能是你改变了上下文的结构,但是可以更新数据库,所以我建议你在保存之前需要更新数据库。

您可以使用数据库迁移命令更新数据库,而无需更改您拥有的数据,如下所示: 转到工具 - &gt;库包管理器 - &gt;包管理器控制台, 在Package Manager Console中运行Enable-Migrations命令, 添加迁移, 更新数据库, 添加迁移(您的项目)

第二种方式解释: IOwinContext接口:它包装OWIN环境字典并提供强类型访问器。 GetOwinContext与HttpContext的接口:获取当前请求的IOwinContext。 与Http Request的GetOwinContext接口:获取当前请求的IOwinContext。 在ApplicationContext的情况下,我们可以这样使用:

Public ApplicationContext:DbContext
{
Public ApplicationContext():base(“ConnectionStringName”)
{
Database.SetInitializer<ApplicationContext>(null);
}
//Dbsets here
}

当我们尝试在这种情况下保存不同的订单时,我们可以使用第二种方案,例如通过存储库模式的工作单元。它也是将数据从一个框架传输到另一个框架的灵活方式。