编辑实体时出现DbUpdateConcurrencyException

时间:2017-08-18 18:33:23

标签: c# entity-framework

我在EF6应用程序中有以下类。

public class Extension
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [ForeignKey("Record")]
    public string RecordId { get; set; }
    public Record Record { get; set; }

    [Key]
    [Column(Order = 2)]
    [DataType(DataType.Date)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Extension Date")]
    public DateTime ExtensionDate { get; set; }

    [Required]
    [Range(1, 100)]
    [Display(Name = "Days Extended")]
    public int DaysExtended { get; set; }

    [Required]
    [Display(Name = "Details")]
    public string Details { get; set; }

    [Required]
    [ForeignKey("ExtendedByUser")]
    public string ExtendedByUserId { get; set; }
    public ApplicationUser ExtendedByUser { get; set; }
}

public class Record
{
    // Id
    [Key]
    public string Id { get; set; }

    // Status
    [Required]
    public RecordStatus Status { get; set; }

    // Date Created
    [Required]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date Created")]
    public DateTime DateCreated { get; set; }

    // Created By
    [ForeignKey("CreatedByUser")]
    public string CreatedByUserId { get; set; }
    public ApplicationUser CreatedByUser { get; set; }

    // Date of last edit
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime? LastEditedDate { get; set; }

    // User who performed last edit
    [ForeignKey("LastEditedByUser")]
    public string LastEditedByUserId { get; set; }
    public ApplicationUser LastEditedByUser { get; set; }

    // Submission date
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date Submitted")]
    public DateTime? SubmissionDate { get; set; }

    // User who submitted the record
    [ForeignKey("SubmittedByUser")]
    public string SubmittedByUserId { get; set; }
    public ApplicationUser SubmittedByUser { get; set; }
}

ApplicationUser类只是Visual Studio ASP.NET MVC模板创建的用户的默认类。

我能够创建Extensions并将它们保存到数据库中,但是当我尝试编辑它们时,我得到了一个DbUpdateConcurrencyException。例如,以下代码会一直抛出异常。

class Program
{
    static void Main(string[] args)
    {
        using (ApplicationDbContext db = new ApplicationDbContext())
        {
            Extension extension = new Extension
            {
                Details = "Details for a new extension.",
                DaysExtended = 25,
                ExtendedByUserId = db.Users.First().Id,
                RecordId = db.Records.First().Id,
                ExtensionDate = DateTime.Now
            };

            // create
            db.Extensions.Add(extension);
            db.SaveChanges(); // <-- Works

            // now edit
            extension.Details = "some new details";
            extension.DaysExtended = 40;

            db.SaveChanges(); // <-- Fails every time
        }
    }
}

有人可以说清楚为什么会这样吗?我知道该异常意味着该条目已被加载到上下文中,但是没有理由在创建条目和修改条目之间更改记录。

如果需要更多信息,请与我们联系。

更新

好吧,我能解决它......

C#DateTime对象和&#34; datetime&#34; SQL Server中的数据类型存在兼容性问题。不知何故,存储在我的Extension对象中的DateTime被认为不等于&#34; datetime&#34;存储在数据库中的值。这会导致Entity Framework在我尝试更新Extension记录时抛出并发异常,因为它认为自加载条目以来值已经更改。

就我而言,有两种方法可以解决这个问题(我选择了后者,因为它与我原来的意图更加一致)。

  1. 将用于表示ExtensionDate属性的列的数据类型设置为&#34; datetime2&#34;。
  2. 将用于表示ExtensionDate属性的列的数据类型设置为&#34; date&#34;并且在使用DateTime时仅使用日期。
  3. 我会将此作为答案发布,但我想在发布之前了解不兼容的确切原因。有谁知道为什么这两种类型不兼容?

1 个答案:

答案 0 :(得分:1)

这是由于与存储在SQL Server中的值相比,存储在内存中的DateTime.Now的值。 datetime的时间范围可以存储在00:00:00 through 23:59:59.997之间。 datetime2的存储范围较大,为00:00:00 through 23:59:59.9999999