如果不保留对并发检查的专用列,您仍然可以处理并发性。有些数据库不支持 RowVersion / Timestamp 类型的列。在这些类型的场景中,您可以使用Data Annotation或Fluent API配置来配置一个或多个用于并发检查的字段。
配置非时间戳字段
Convention None
Data Annotation [ConcurrencyCheck]
Fluent API .IsConcurrencyToken()
1) Data Annotation修改 Student 类,以使用 [ConcurrencyCheck] Data Annotation属性:
public class Student { public int StudentId { get; set; } [ConcurrencyCheck] public string RollNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }当应用程序运行时,代码首先创建 Students 表(参见下图)。数据库在 RollNumber 列中不为 [ConcurrencyCheck] 属性做任何特殊的事情。
但是当任何修改/更改发生在Students表时,代码首先处理并发检查。接下来阅读代码如何创建更新和删除并处理并发检查。
UPDATE SQL exec sp_executesql N'UPDATE [dbo].[Students] SET [RollNumber] = @0 WHERE (([StudentId] = @1) AND ([RollNumber] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'2',@1=1,@2=N'1'注意 WHERE 条件。它在更新记录时比较 StudentId (主键)和 RollNumber 。
DELETE SQL exec sp_executesql N'DELETE [dbo].[Students] WHERE (([StudentId] = @0) AND ([RollNumber] = @1))',N'@0 int,@1 nvarchar(max) ',@0=1,@1=N'2'在删除 Students 表的记录时,它还检查 StudentId 和 RollNumber 列值。如果 RollNumber 列值改变了,你现在正在更新那个记录,然后你就会得到OptimisticConcurrencyException。
2) Fluent API使用Code First的 IsConcurrencyToken() 方法来处理非时间戳字段的并发性。
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Student>().Property(s => s.RollNumber).IsConcurrencyToken(); base.OnModelCreating(modelBuilder); } 注意为了测试并发效果,添加代码来更新Students表中已有的记录如下:
var student = context.Students.FirstOrDefault(u => u.StudentId == 1); if (student != null) { student.RollNumber = "2"; context.SaveChanges(); }在Visual Studio中为 context.SaveChanges() 行添加断点。在 SaveChanges() 方法执行之前,修改数据库中 Students 表记录条件是StudentId = 1。
UPDATE Students SET RollNumber = '123' WHERE StudentId = 1;现在,如果你要执行下一行语句savechanges()然后你会得到如下的一个提示:
DbUpdateConcurrencyException:
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
DbUpdateConcurrencyException 异常抛出,因为记录已经修改为只读。
总结在本文中,我们学习了如何通过Entity Framework Code First将专用字段保存在表中,或者通过添加特殊data annotation属性或Fluent API配置来配置处理乐观并发性的方法。
欢迎转载,转载请注明翻译原文出处(本文章),原文出处(原博客地址),然后谢谢观看
如果觉得我的翻译对您有帮助,请点击推荐支持:)