在EF Core中通过自定义特性配置IsConcurrencyToken实现乐观并发
EF Core 7.0 基于特性配置乐观并发控制
我需要在EF Core 7.0.0的DbContext的OnModelCreating(ModelBuilder modelBuilder)方法中,通过模型Row Version属性上的自定义特性来启用或禁用乐观并发控制。此前已在.NET Framework 4.8中实现该功能,现在要在EF Core项目中完成相同配置。
我定义了带有Version属性的IVersionedEntity接口,以及可设置是否启用乐观并发的自定义LockAttribute特性,同时给出了.NET Framework中的实现扩展方法,但不清楚EF Core的ModelBuilder该如何进行此类配置。
自定义特性代码
[AttributeUsage(AttributeTargets.Property, Inherited = true)] public class LockAttribute : Attribute { public bool IsEnabled { get; private set; } public LockAttribute(bool isEnabled = true) { IsEnabled = isEnabled; } }
.NET Framework中的原有实现
public static void ConfigureLocking(this DbModelBuilder modelBuilder) { modelBuilder.Types<IVersionedEntity>().Configure(configuration => { var versionPropertyInfo = configuration.ClrType.GetProperty("Version"); var lockAttribute = versionPropertyInfo.GetCustomAttribute<LockAttribute>(true); if (lockAttribute != null) { configuration.Property(entity => entity.Version).IsRowVersion().IsConcurrencyToken(lockAttribute.IsEnabled); } }); }
EF Core 7.0中的实现方案
在EF Core中,我们可以通过ModelBuilder遍历所有实现IVersionedEntity的实体,再针对每个实体的Version属性进行配置:
public static void ConfigureLocking(this ModelBuilder modelBuilder) { // 遍历所有实现IVersionedEntity的实体类型 foreach (var entityType in modelBuilder.Model.GetEntityTypes() .Where(t => typeof(IVersionedEntity).IsAssignableFrom(t.ClrType))) { // 获取Version属性的PropertyInfo var versionProperty = entityType.ClrType.GetProperty(nameof(IVersionedEntity.Version)); if (versionProperty == null) continue; // 获取属性上的LockAttribute var lockAttribute = versionProperty.GetCustomAttribute<LockAttribute>(true); if (lockAttribute == null) continue; // 配置RowVersion和并发令牌 var propertyBuilder = modelBuilder.Entity(entityType.ClrType) .Property(nameof(IVersionedEntity.Version)); propertyBuilder.IsRowVersion(); propertyBuilder.IsConcurrencyToken(lockAttribute.IsEnabled); } }
使用方式
在DbContext的OnModelCreating方法中调用该扩展方法即可:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ConfigureLocking(); }
内容的提问来源于stack exchange,提问作者Zserbinator
相关产品推荐
相关产品推荐

