You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 8中如何通过实体拆分实现RuleApp多版本存储?

实现EF Core 8下的RuleApp版本控制(一对多关联)

1. 定义实体类

先创建两个实体类,分别对应存储唯一规则应用的主表,以及存储版本快照的版本表:

RuleApp 实体(主表)

public class RuleApp
{
    public int Id { get; set; }
    // 唯一名称,添加唯一约束确保只保存一次
    public string Name { get; set; } = string.Empty;

    // 导航属性:一个RuleApp对应多个版本
    public ICollection<RuleAppRevision> Revisions { get; set; } = new List<RuleAppRevision>();
}

RuleAppRevision 实体(版本表)

public class RuleAppRevision
{
    public int Id { get; set; }
    // 外键:关联到所属的RuleApp
    public int RuleAppId { get; set; }
    // 版本标识,可自定义规则(如v1、20240520-001)
    public string VersionNumber { get; set; } = string.Empty;
    // 版本创建时间
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

    // 序列化存储的JSON属性
    public string Rules { get; set; } = string.Empty;
    public string Entities { get; set; } = string.Empty;
    public string DataElements { get; set; } = string.Empty;

    // 导航属性:关联到对应的RuleApp
    public RuleApp RuleApp { get; set; } = null!;
}

2. DbContext 配置

在你的DbContext子类中,通过Fluent API配置一对多关联、唯一约束和JSON列映射:

public class YourDbContext : DbContext
{
    public DbSet<RuleApp> RuleApps { get; set; }
    public DbSet<RuleAppRevision> RuleAppRevisions { get; set; }

    public YourDbContext(DbContextOptions<YourDbContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 配置RuleApp名称的唯一约束
        modelBuilder.Entity<RuleApp>()
            .HasIndex(r => r.Name)
            .IsUnique();

        // 配置一对多关联:RuleApp包含多个Revision,Revision属于单个RuleApp
        modelBuilder.Entity<RuleApp>()
            .HasMany(r => r.Revisions)
            .WithOne(r => r.RuleApp)
            .HasForeignKey(r => r.RuleAppId)
            .OnDelete(DeleteBehavior.Cascade); // 删除RuleApp时自动删除所有版本,可根据需求调整为Restrict

        // 配置JSON列(SQL Server用nvarchar(max),PostgreSQL可改为jsonb)
        modelBuilder.Entity<RuleAppRevision>()
            .Property(r => r.Rules)
            .HasColumnType("nvarchar(max)");
        modelBuilder.Entity<RuleAppRevision>()
            .Property(r => r.Entities)
            .HasColumnType("nvarchar(max)");
        modelBuilder.Entity<RuleAppRevision>()
            .Property(r => r.DataElements)
            .HasColumnType("nvarchar(max)");

        // 可选:用HasConversion实现强类型与JSON的自动序列化/反序列化
        // 假设你有RulesModel强类型类,示例配置:
        // modelBuilder.Entity<RuleAppRevision>()
        //     .Property(r => r.Rules)
        //     .HasConversion(
        //         v => JsonSerializer.Serialize(v, new JsonSerializerOptions { WriteIndented = true }),
        //         v => JsonSerializer.Deserialize<RulesModel>(v, new JsonSerializerOptions { WriteIndented = true })!)
        //     .HasColumnType("nvarchar(max)");
    }
}

3. 创建新版本的逻辑

当用户需要基于某个版本修改并生成新版本时,直接复制源版本的JSON属性,创建新的RuleAppRevision实例并关联到同一个RuleApp即可:

public async Task CreateNewRevisionAsync(int ruleAppId, int sourceRevisionId, string newVersionNumber)
{
    using var context = new YourDbContext(_options);
    
    var sourceRevision = await context.RuleAppRevisions
        .FirstOrDefaultAsync(r => r.Id == sourceRevisionId && r.RuleAppId == ruleAppId);
    
    if (sourceRevision == null)
        throw new InvalidOperationException("指定的源版本不存在");
    
    var newRevision = new RuleAppRevision
    {
        RuleAppId = ruleAppId,
        VersionNumber = newVersionNumber,
        Rules = sourceRevision.Rules,
        Entities = sourceRevision.Entities,
        DataElements = sourceRevision.DataElements,
        CreatedAt = DateTime.UtcNow
    };
    
    context.RuleAppRevisions.Add(newRevision);
    await context.SaveChangesAsync();
}

补充说明

  • 版本号唯一性:可给RuleAppRevision的VersionNumber和RuleAppId添加联合唯一索引,确保同一RuleApp下版本号不重复。
  • JSON列优化:如果使用PostgreSQL,建议用jsonb类型,支持索引和更高效的查询;SQL Server可考虑开启JSON索引提升查询性能。

内容的提问来源于stack exchange,提问作者Furqan Safdar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:46:25