在 EF Core 中使用注解配置 IsConcurrencyToken(value)

问题描述 投票:0回答:1

我希望能够在

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 中的类非常不同,我不知道如何使用该类配置这样的东西。

c# entity-framework entity-framework-core optimistic-concurrency rowversion
1个回答
1
投票

在 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();
© www.soinside.com 2019 - 2024. All rights reserved.