ASP.NET MVC5 从多个实例访问一个对象

本文关键字:实例 访问 一个对象 NET MVC5 ASP | 更新日期: 2023-09-27 17:56:27

我有以下代码,用于使用 C# ASP.NET MVC5 的 Web 应用程序

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var Db = new ApplicationDbContext();
        var user = await UserManager.FindAsync(model.UserName, model.Password);
        if (user != null)
        {
            await SignInAsync(user, model.RememberMe);
            user.LastLogin = DateTime.UtcNow;
            Db.Entry(user).State = System.Data.Entity.EntityState.Modified;
            await Db.SaveChangesAsync();
            return RedirectToLocal(returnUrl);
        }
        else
        {
            ModelState.AddModelError("", "Invalid username or password.");
        }
    }
    // If we got this far, something failed, redisplay form
    return View(model);
}

我想做的是使用相同的对象来执行两个不同的任务: 1. 登录验证 2. 更新对象的数据。数据保存在 SQL Server 数据库中。

上面的代码抛出了一个异常,上面写着:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

有谁知道我应该如何缓解这种情况?

编辑 #1这就是我的构造函数的样子。

public AccountController(): this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
    UserManager = userManager;
}

ASP.NET MVC5 从多个实例访问一个对象

好的,

我找到了解决方案

我所做的是通过分配不同的对象。并在单独的上下文中使用该对象。

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var Db = new ApplicationDbContext();
            var user = await UserManager.FindAsync(model.UserName, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);
                var temp = Db.Users.Find(user.UserName);
                temp.LastLogin = DateTime.UtcNow;
                Db.Entry(temp).State = EntityState.Modified;
                await Db.SaveChangesAsync();
                return RedirectToLocal(returnUrl);
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }
        // If we got this far, something failed, redisplay form
        return View(model);
    }

您已经有一个上下文可以使用,您可以将其传递到UserStore中。您可以重复使用它,而不必处理多个上下文。

public class AccountController : Controller
{
    public AccountController ()
    {
        Context = new ApplicationDbContext()
        UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(Context));
    }
    protected ApplicationDbContext Context { get; private set; }
    protected UserManager<User> UserManager { get; private set; }
}

现在只需使用 Context 获取对数据库的引用。我还建议研究一个BaseController类来保存它以供重用,并使用一个Unit of Work模式来保存您的上下文。