【发布时间】:2019-08-26 03:50:25
【问题描述】:
我不确定为什么在尝试创建一个 1:many 的实体时 EF 尝试在 Asp Net Users 中添加新条目,而不是更新 1:many
我有一个user,其中有很多items
SqlException:违反主键约束“PK_AspNetUsers”。无法在对象“dbo.AspNetUsers”中插入重复键。重复键值为(cdbb1f2f-ddcf-40c0-97ec-f50f8049d87a)。
public class Context : IdentityDbContext
{
public Context(DbContextOptions options) : base(options)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Item> Items { get; set; }
public DbSet<File> Files { get; set; }
}
public class User : IdentityUser
{
public List<Item> Items { get; set; } = new List<Item>();
}
public class Item
{
private Item()
{
}
public Item(string title, User owner, File file)
{
Title = title;
Owner = owner;
File = file;
}
public int Id { get; private set; }
public string Title { get; set; }
public User Owner { get; set; }
public File File { get; set; }
public DateTime CreationDate { get; } = DateTime.Now;
}
这就是问题所在:
var fileResult = await _file.SaveFile(input.File);
var item = new Item(input.Title, user, fileResult.File);
user.Items.Add(item);
await _context.Items.AddAsync(item);
await _context.SaveChangesAsync();
用户已加载:
public User GetUser()
{
return _context.Users.FirstOrDefault(x => x.UserName == _http.HttpContext.User.Identity.Name);
}
我试过了:
当我改变时
public Item(string title, User owner, File file)
{
Title = title;
Owner = owner;
File = file;
}
只是:
public Item(string title, File file)
{
Title = title;
File = file;
}
并让它由以下人员处理:
user.Items.Add(item);
那么 DB 中的 OwnerId 为空
使用:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.HasMany(x => x.Items)
.WithOne(x => x.Owner);
modelBuilder.Entity<Item>().HasOne(x => x.Owner);
}
也无济于事
【问题讨论】:
-
您需要将
public Guid OwnerId {get; set;}添加到您的项目的类中,并填写用户ID。这样 EF 就会隐含地理解 Item 和 User 之间存在 1:many 的关系。 -
@Dennis1679
user.Items.Add(item);item.Owner = user;item.OwnerId = user.Id;withmodelBuilder.Entity<User>().HasMany(x => x.Items).WithOne(x => x.Owner).HasForeignKey(x => x.OwnerId);and once again违反主键约束'PK_AspNetUsers` -
关于我之前的评论;我不是 100% 确定,但我认为 - 如果你想建立关系而不在 fluent API 中指定它 - 你需要分别将 Owner 重命名为 User 和 UserId。
-
看起来
user变量中的对象没有被上下文跟踪(否则user.Items.Add(item);就足够了,你不需要await _context.Items.AddAsync(item);并且不会得到异常)。你能验证一下 - 看看Debug.Assert(_context.Users.Local.Contains(user));是否失败? -
@IvanStoev 你给了我一个很大的提示,现在我意识到是什么导致了这个问题。我将
(options => options.UseSqlServer(Configuration["Database:ConnectionString"]), ServiceLifetime.Transient);更改为(options => options.UseSqlServer(Configuration["Database:ConnectionString"]), ServiceLifetime.Scoped);(DI Lifetime),它工作正常。谢谢!
标签: asp.net-core entity-framework-core