我有一个引用AppUser模型的Question模型。这是1对*的关系,因为1个AppUser有很多问题,而一个问题属于1个AppUser。我的Question类如下所示:

public class Question
{
    public int Id { get; set; }
    public string Subject { get; set; }
    public string Text { get; set; }
    public DateTime Date { get; set; }
    public int NumOfViews { get; set; }
    public AppUser LastAnswerBy { get; set; }

    public AppUser AppUser { get; set; }
    public ICollection<Comment> Comments { get; set; }
}

所以我尝试像这样在 Controller 中的数据库中添加一个新的Question:
[HttpPost]
    public ActionResult PostQuestion(Question question)
    {
        if (ModelState.IsValid)
        {
            var id = User.Identity.GetUserId();
            var user = UserManager.Users.FirstOrDefault(x => x.Id == id);
            question.Date = DateTime.Now;
            question.AppUser = user;

            _context.Questions.Add(question);
            _context.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(question);
    }

    private AppUserManager UserManager
    {
        get { return HttpContext.GetOwinContext().GetUserManager<AppUserManager>(); }
    }

有了这段代码,我得到了这样的异常:
IEntityChangeTracker的多个实例不能引用一个实体对象。因此,经过一番搜索之后,似乎出现的问题是我的 Controller 和AppUserManager类具有DbContext的2个不同实例,解决方案是将其注入(inject)到这些类中。将其注入(inject)到我的 Controller 中没问题,但是我不知道如何将其注入(inject)到我的UserManager类中,如下所示:
public class AppUserManager : UserManager<AppUser>
{

    public AppUserManager(IUserStore<AppUser> store)
        : base(store)
    { }

    public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options,
    IOwinContext context)
    {
        AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
        AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db));

        return manager;
    }
}

从我的IdentityConfig类中调用它,如下所示:
public class IdentityConfig
{
    public void Configuration(IAppBuilder app)
    {
        app.CreatePerOwinContext<AppIdentityDbContext>(AppIdentityDbContext.Create);
        app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
        app.CreatePerOwinContext<AppRoleManager>(AppRoleManager.Create);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
        });

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}

我的问题可能是我不太了解身份部分。任何帮助是最感激的

解决方案:
正如Tobias所说,我正在使用2种不同的上下文来更新数据库。获得这样的上下文可以正常工作:
private AppIdentityDbContext Context
    {
        get { return HttpContext.GetOwinContext().Get<AppIdentityDbContext>(); }
    }

最佳答案

您的问题很可能是您尝试使用两种不同的上下文来做一件事情。您正在使用一种上下文找到用户,并尝试使用另一种上下文来更新数据库。为了解决这个问题,您应该像这样在 Controller 中实例化上下文:

_context = HttpContext.GetOwinContext().Get<AppIdentityDbContext>();

这样,您将获得用于实例化AppUserManager的相同上下文。

如果我弄错了或不清楚,请发表评论。 :)

10-05 18:52