我希望能够在
EF Core 7.0.0中的
OnModelCreating(ModelBuilder modelBuilder)
的 DbContext
方法中使用模型的行版本属性上的属性启用或禁用乐观并发。我能够在 .NET Framework 4.8 中使用它,但我也需要在 EF Core 项目中使用它。
我有一个实体接口,它有一个名为
Version
的IVersionedEntity
属性,我想使用一个自定义属性,我可以在其中定义是否要启用或禁用乐观并发。
属性:
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class LockAttribute : Attribute
{
public bool IsEnabled { get; private set; }
public LockAttribute(bool isEnabled = true)
{
IsEnabled = isEnabled;
}
}
我知道我可以在
OnModelCreating(DbModelBuilder modelBuilder)
方法中使用 ASP.NET (.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);
}
});
}
我的问题是,
ModelBuilder
EF Core 中的类非常不同,我不知道如何使用该类配置这样的东西。
在 EF Core 7.0+ 中,可以通过自定义 模型构建约定相对容易地完成。事实上,所有预定义的 EF Core 数据注释都使用类似于这样的约定类来处理:
public class LockAttributeConvention : PropertyAttributeConventionBase<LockAttribute>
{
public LockAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) : base(dependencies) { }
protected override void ProcessPropertyAdded(IConventionPropertyBuilder propertyBuilder, LockAttribute attribute, MemberInfo clrMember, IConventionContext context)
{
if (attribute.IsEnabled)
{
propertyBuilder.ValueGenerated(ValueGenerated.OnAddOrUpdate, fromDataAnnotation: true);
propertyBuilder.IsConcurrencyToken(true, fromDataAnnotation: true);
}
}
}
注册它的帮助方法:
public static ModelConfigurationBuilder AddLockAttributeSupport(this ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Add(sp => new LockAttributeConvention(
sp.GetRequiredService<ProviderConventionSetBuilderDependencies>()));
return configurationBuilder;
}
最后从
ConfigureConventions
override 调用它:
configurationBuilder.AddLockAttributeSupport();