我在通过DbContext.Add(.)添加一个新实体时遇到了问题方法。在DbContext.SaveChanges()上,我得到一个DbUpdateConcurrencyException。我在试着插入数据库。我是应用程序的唯一开发人员,运行localhost,而且数据库表是原始的。没有用户。就我一个人。
这一点也没有帮助,尽管它类似:
向数据库添加新行时的实体框架6 DbUpdateConcurrencyException
我每个请求使用一个DbContext。如下所示:
在DbContext MVC中,每个请求只有一个ASP.NET (没有IOC容器)
我正在注销由实体框架生成的sql语句,如下所示:
https://stackoverflow.com/a/20751723/2088914
下面是模型(先编写代码,然后进行迁移)。当我发帖时,我只提供关联、角色、分配和删除标志。行id自动设置为0,因为我没有从客户端提供它,date也是一个默认值,然后我在服务器上填充它-所有预期的内容:
public class Permission {
[Column("row_id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RowId { get; set; }
[Key]
[StringLength(10)]
[Column("associate_nt_id", Order = 0)]
[Required]
public string AssociateNtId { get; set; }
[Key]
[Column("role_name", Order = 1)]
[StringLength(50)]
[Required]
public string RoleName { get; set; }
[Key]
[Column("eff_ts", Order = 2)]
[Required]
public DateTime EffectiveTimestamp { get; set; }
[StringLength(10)]
[Column("assignor_nt_id")]
[Required]
public string RoleAssignorNtId { get; set; }
[Column("deleted")]
[Required]
public bool Deleted { get; set; }
}我有一个带有post方法的web控制器,它被一个角spa成功地访问,并且模型被填充:
[HttpPost]
[Route("")]
[Require(Roles.admin)]
public Permission Post(Permission permission) {
permission.EffectiveTimestamp = DateTime.Now;
MAPDB.Current.Permissions.Add(permission);
MAPDB.Current.Database.Log = s => {
Debug.WriteLine(s);
};
MAPDB.Current.SaveChanges();
return permission;
}我在visual studio 2015中运行调试。以下是错误消息:

下面是实体框架正在生成的sql:
INSERT [dbo].[_permissions]([associate_nt_id], [role_name], [eff_ts], [assignor_nt_id], [deleted])
VALUES (@0, @1, @2, @3, @4)
SELECT [row_id]
FROM [dbo].[_permissions]
WHERE @@ROWCOUNT > 0 AND [associate_nt_id] = @0 AND [role_name] = @1 AND [eff_ts] = @2
-- @0: 'associate' (Type = String, Size = 10)
-- @1: 'user' (Type = String, Size = 50)
-- @2: '9/20/2017 12:49:05 PM' (Type = DateTime2)
-- @3: 'assignor' (Type = String, Size = 10)
-- @4: 'True' (Type = Boolean)
-- Executing at 9/20/2017 12:49:05 PM -05:00
-- Completed in 24 ms with result: SqlDataReade
-- Closed connection at 9/20/2017 12:49:05 PM -05:00它似乎是在记录器中执行的,该语句与我所期望的完全相同,除非没有发生任何数据库插入。如果我从记录器中取出语句,填写参数并通过sql客户端执行它,它将工作并返回所创建内容的行id。我不明白问题是什么--不存在并发情况,不应该缺少/添加列,没有无效的参数,没有将列映射到对象属性的问题,没有密钥冲突,也没有标识列的问题。
如何才能让实体框架只插入这个新对象(而不吞并异常)?
谢谢你的帮助。
发布于 2017-09-20 19:46:24
这个问题很可能是由PK (EffectiveTimestamp)的DateTime部分引起的。将插入记录,但SELECT不会找到它,因为在默认情况下,EF将DateTime属性映射到日期时间列,而正如您从日志中看到的那样,参数类型是datetime2,这具有更高的精度,因此当存储到表列时它会被截断,因此select筛选器的[eff_ts] = @2部分不匹配。
要查看是否存在这种情况,您可以尝试微调时间值:
// ...
var time = DateTime.Now;
permission.EffectiveTimestamp = new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second);
// ...如果这起作用(正如我预期的那样),您可能会考虑更改数据库列类型:
[Key]
[Column("eff_ts", Order = 2, TypeName="datetime2")]
[Required]
public DateTime EffectiveTimestamp { get; set; }发布于 2022-03-14 16:48:54
我也有这个问题。显然,夏令节省时间把EF在内存中缓存的所有记录都搞砸了。我通过打开Microsoft.EntityFrameworkCore.Database.Command,的信息日志( Information )了解到了这一点,它应该是一个INSERT语句,它是一个非常疯狂的合并语句.重新设置服务修复了它。谢谢,日光节约时间..。
https://stackoverflow.com/questions/46329094
复制相似问题