ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c#-添加时出现DbUpdateConcurrencyException

2019-10-25 18:04:33  阅读:551  来源: 互联网

标签:asp-net-web-api entity-framework-6 c entity-framework sql-server


我在通过DbContext.Add(…)方法添加新实体时遇到问题.在DbContext.SaveChanges()上,我得到一个DbUpdateConcurrencyException.我正在尝试插入数据库.我是应用程序上唯一的运行本地主机的开发人员,数据库表是原始数据.没有用户.只有我.

尽管类似,但这没有帮助:
Entity Framework 6 DbUpdateConcurrencyException When Adding New Rows To Database

我在每个请求中使用一个DbContext.像这样:
One DbContext per request in ASP.NET MVC (without IOC container)

我正在注销由实体框架生成的sql语句,如下所示:
https://stackoverflow.com/a/20751723/2088914

这是模型(代码优先,带有迁移).发布时,我仅提供关联,角色,分配者和已删除标志.由于我没有从客户端提供行ID,因此行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 api控制器,该方法已被角度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中的调试中运行.这是错误消息:
enter image description here

这是实体框架生成的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

它似乎已在logger中执行,并且该语句正是我所期望的,但没有发生数据库插入.如果我从记录器中取出该语句,填写参数,然后通过sql客户端执行该语句,它将起作用并返回所创建内容的行ID.我不明白问题是什么-没有并发情况发生,没有应该丢失/添加的列,没有无效参数,没有将列映射到对象属性的问题,没有键冲突,没有标识列的问题.

如何获得实体框架以仅插入这个新对象(不吞咽异常)?

谢谢您的帮助.

解决方法:

此问题最有可能是由PK(EffectiveTimestamp)的DateTime部分引起的.插入了记录,但是SELECT找不到它,因为默认情况下EF将DateTime属性映射到datetime列,而从日志中可以看到,参数类型为datetime2,它具有更高的精度,因此被截断了当存储到表列时,因此与选择过滤器的[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; }

标签:asp-net-web-api,entity-framework-6,c,entity-framework,sql-server
来源: https://codeday.me/bug/20191025/1930465.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有