簡體   English   中英

為什么EF嘗試插入當前登錄的用戶?

[英]Why is EF trying to insert currently logged in user?

我試圖將用戶身份驗證添加到現有應用程序中。 嘗試添加新產品時,出現以下錯誤:

“ MySqlException:鍵'PRIMARY'的重復條目'a82c1468-b942-4c48-a787-defdc584641d'”。

我正在使用EF Core 1.1.2

這是我的ApplicationDbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }

    public virtual DbSet<Review> Reviews { get; set; }
    public virtual DbSet<Product> Products { get; set; }
}

這是我的啟動課程:

public class Startup
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json");
        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddEntityFrameworkMySql()
                .AddDbContext<ApplicationDbContext>(options =>
                              options.UseMySql(Configuration["ConnectionStrings:DefaultConnection"]));

        // This is for Identity
        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseIdentity();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Account}/{action=Index}/{id?}");  // <-There is an edit here
        });//there is a change here for idenity

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

這是將新產品插入數據庫的“ Create操作方法:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Product product, ICollection<IFormFile> files = null)
{
    if (files != null)
    {
        foreach (var file in files)
        {
            if (file.Length > 0)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    file.CopyTo(ms);
                    byte[] fileBytes = ms.ToArray();
                    product.ProductImg = fileBytes;
                }
            }
        }
    }

    var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    var currentUser = await _userManager.FindByIdAsync(userId);
    product.User = currentUser;

    if (ModelState.IsValid)
    {
        _context.Save(product);
        return RedirectToAction("Index");
    }

    return View(product);
}

這是我的RegisterLogin方法:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;

    if (ModelState.IsValid)
    {
        Microsoft.AspNetCore.Identity.SignInResult result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, isPersistent: true, lockoutOnFailure: false);

        if (result.Succeeded)
        {
            _logger.LogInformation(1, "User logged in.");
            return RedirectToLocal(returnUrl);
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return View(model);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;

    if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await _userManager.CreateAsync(user, model.Password);

        if (result.Succeeded)
        {
            _logger.LogInformation(3, "User created a new account with password.");
            return RedirectToLocal(returnUrl);
        }
    }

    return View(model);
}

這是我的Product模型類:

public class Product
{
    [Key]
    public int ProductId { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    [DisplayFormat(DataFormatString = "{0:c}")]
    public double Cost { get; set; }

    [Required]
    [Display(Name = "Country of Origin")]
    public string CountryOfOrigin { get; set; }

    [Display(Name = "Product Image")]
    public byte[] ProductImg { get; set; }

    [DisplayFormat(DataFormatString = "{0:d}")]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime DatePosted { get; set; }

    public virtual ApplicationUser User { get; set; }
    public virtual ICollection<Review> Reviews { get; set; }
}

實體框架無法告訴您要附加到產品的用戶已經存在。 有兩種方法可以解決此問題:

1)明確將狀態設置為“不變”:

context.Entry(product.User).State = EntityState.Unchanged; 

2)在產品實體上公開FK用戶ID。 這里

product.UserId = userId

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM