编辑实体时的 DbUpdateConcurrencyException



我在 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; }
}

应用程序用户类只是由 Visual Studio ASP.NET MVC 模板创建的用户的默认类。

我能够创建扩展并将它们保存到数据库中,但是当我尝试编辑它们时,我得到了一个 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
}
}
}

有人可以阐明为什么会发生这种情况吗?我知道异常意味着该条目在加载到上下文中后已被修改,但是没有理由在创建条目和修改条目之间

更改记录。如果需要更多信息,请告诉我。

更新

好吧,我能够修复它...

SQL Server 中的 C# DateTime 对象和"datetime"数据类型存在兼容性问题。不知何故,存储在我的扩展对象中的日期时间被视为不等于存储在数据库中的"日期时间"值。这会导致实体框架在我尝试更新扩展记录时引发并发异常,因为它认为自加载条目以来值已更改。

就我而言,有两种方法可以解决这个问题(我选择了后者,因为它更符合我的初衷(。

  1. 将用于表示 ExtensionDate 属性的列的数据类型设置为"datetime2"。
  2. 将用于表示 ExtensionDate 属性的列的数据类型设置为"date",并在使用 DateTime 时仅使用 Date。

我会将其作为答案发布,但我想知道在发布之前不兼容的确切原因。有谁知道为什么这两种类型不兼容?

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

相关内容

  • 没有找到相关文章

最新更新