代码很简单。Tag.cs
实体:
public partial class Tag
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
HomeController.cs
类:
public async Task<IActionResult> Index()
{
tagRepository.Insert(new Tag
{
Name = "name",
Description = "description"
});
await UnitOfWork.SaveChangesAsync(); // calls dbContext.SaveChangesAsync()
return View();
}
TagRepository.cs
类:
// Context it's a usual DBContext injected via Repository's constructor
public virtual void Insert(TEntity item)
=> Context.Entry(item).State = EntityState.Added;
运行以下命令来创建标签
表:
CREATE TABLE Tag (
ID SERIAL PRIMARY KEY,
Name text NOT NULL,
Description text NULL
);
运行我的应用程序时,出现错误:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (28ms) [Parameters=[@p0='?', @p1='?', @p2='?'], CommandType='Text', CommandTimeout='30']
INSERT INTO "tag" ("id", "description", "name")
VALUES (@p0, @p1, @p2);
Npgsql.PostgresException (0x80004005): 23505: duplicate key value violates unique constraint "tag_pkey"
at Npgsql.NpgsqlConnector.<DoReadMessage>d__157.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at Npgsql.NpgsqlConnector.<ReadMessage>d__156.MoveNext()
从下面可以看到,实体框架试图向数据库发送id=0
的值,但是我的数据库中已经存在一个记录与id=0
相同,这就是为什么它抛出重复键
错误。
我目前还没有找到任何答案,我的问题是:如何摆脱这个错误,并告诉实体框架我的id
列是自动增加的,不需要更新它?
Scaffold-DbContext
),有趣的是,所有实体中的id
属性都使用.Property(p => p.Id).ValueGeneratedNever()
生成。这可能是一个 bug,我猜.. 不管怎样,我已将其替换为.ValueGeneratedOnAdd()
并且它可以工作了。感谢您提供的链接和解释。 - Andrey Kotov