ConcurrencyCheck特性可以应用到领域类的属性中。当EF执行更新操作的时候,Code-First将列的值放在where条件语句中,你可以使用这个CurrencyCheck特性,使用已经存在的列做并发检查,而不是使用单独的TimeStamp列来做并发检查。
看下面的代码:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EF2 { [Table("StudentInfo")] public class Student { [Key] [Column(Order=)] public int StudentKey1 { get; set; } [Key] [Column(Order=)] public int StudentKey2 { get; set; } [Column("Name",TypeName="ntext")] [MaxLength()] [ConcurrencyCheck] public string StudentName { get; set; } [NotMapped()] public int? Age { get; set; } public int StdId { get; set; } [ForeignKey("StdId")] public virtual Standard Standard { get; set; } [Timestamp] public byte[] RowVersion { get; set; } } }
然后我们来修改一下Main函数测试的代码:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EF2 { class Program { static void Main(string[] args) { Student stuModel1 = null; Student stuModel2 = null; using (var db = new DbContextClass()) { stuModel1 = db.Students.Where(s => s.StudentKey1 == && s.StudentKey2 == ).Single(); } using (var db = new DbContextClass()) { stuModel2 = db.Students.Where(s => s.StudentKey1 == && s.StudentKey2 == ).Single(); } stuModel1.StudentName = "Test Only For one"; stuModel2.StudentName = "Test Only For twos"; try { using (var db = new DbContextClass()) { db.Entry(stuModel1).State = EntityState.Modified; db.SaveChanges(); } } catch (DbUpdateConcurrencyException ex) { Console.WriteLine(ex.Message); } try { using (var db = new DbContextClass()) { db.Entry(stuModel2).State = EntityState.Modified; db.SaveChanges(); } } catch (DbUpdateConcurrencyException ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); } } }
然后错误并发消息是:
exec sp_executesql N'UPDATE [dbo].[StudentInfo] SET [StudentName] = @, [StdId] = @ WHERE ((([StudentKey1] = @) AND ([StudentKey2] = @)) AND ([StudentName] = @)) nvarchar(),@ nvarchar()',@0=N'Test Only For one',@1=1,@2=1,@3=1,@4=N'Test Only For one'
请注意:
Note that TimeStamp attribute can only be applied to a single byte array property in a class, whereas ConcurrencyCheck attribute can be applied to any number of properties with any datatype.
TimeStamp特性只能够被用到单字节属性的类中,但是ConcurrencyCheck特性可以被用到任何数量,任何类型的属性中。