IEntityChangeTracker EF6

时间:2017-04-26 08:44:38

标签: c# entity-framework asp.net-identity

我有以下代码,似乎userManager创建了一个不同的DBContext,而我的companyListService使用不同的DbContext。结果我收到错误消息

  

实体对象不能被多个实例引用   IEntityChangeTracker

           if (ModelState.IsValid)
            {
                try
                {
                    _companyListService.AddCompanyList(
                    new CompanyList(_userManager.FindById(GetUserId()), vm.Name));

                   _companyListService.SaveCompanyList();
                }
                catch (Exception e)
                {
                    _nlogger.Error(e);

                    ViewData["EditError"] = e.Message;
                }
            }

我该如何解决这个问题?有没有办法在userManager dbcontext中停止跟踪?或者更好的方法来使用相同的dbcontext?该应用程序使用标识2.

我可以更改我的代码以传递userId而不是解决问题的用户对象,但我想传递用户对象。

当我通过

关闭跟踪时
Configuration.AutoDetectChangesEnabled = false;

问题也已解决,但这会打破其他部分跟踪我们的要求。

解决此问题的最佳方法是什么?

谢谢,

1 个答案:

答案 0 :(得分:0)

imho,它似乎是一个过于乐观的设计:你假设你的身份数据库和你的业务数据库将永远是相同的(换句话说:身份用户和业务使用来自同一个表)。

使用相同的假设我可以建议以下代码:

        if (ModelState.IsValid)
        {
            try
            {
                _companyListService.AddCompanyList(
                new CompanyList(_userManager.FindById(GetUserId()).UserPK, vm.Name));
                //------------------------------------------------^
                //or in the optimistic design :):
                //new CompanyList(GetUserId(), vm.Name));

               _companyListService.SaveCompanyList();
            }
            catch (Exception e)
            {
                _nlogger.Error(e);

                ViewData["EditError"] = e.Message;
            }
        }

public CompanyList(fkUserType fk, string name) {
    UserId = fk;
    Name = name;
}

在这种情况下,您必须显式声明和配置导航属性的外键。

public class CompanyList {
    public CompanyList(fkUserType fk, string name) {
        UserId = fk;
        Name = name;
    }

    public virtual User {get; set;}
    public fkUserType UserId {get; set;}
}

您可能已经注意到,构造函数不再使用实体,只使用密钥。