我试图将用户身份验证添加到现有应用程序。在尝试添加新产品时,我遇到了错误:
" MySqlException:重复条目' a82c1468-b942-4c48-a787-defdc584641d'关键' PRIMARY'"。
我正在使用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; }
}
这是我的Startup类:
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);
}
以下是我的Register
和Login
方法:
[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; }
}
答案 0 :(得分:1)
实体框架无法判断您附加到产品的用户是否已存在。有几种方法可以解决这个问题:
1)将状态显式设置为Unchanged:
context.Entry(product.User).State = EntityState.Unchanged;
2)在您的产品实体上公开FK UserId。见here
product.UserId = userId