forked from xiongyuxing/tiku-backend.net
264 lines
12 KiB
C#
264 lines
12 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
using Tiku.Domain.Catalog;
|
|
using Tiku.Domain.Content;
|
|
using Tiku.Domain.Identity;
|
|
using Tiku.Domain.QuestionBanks;
|
|
|
|
namespace Tiku.Infrastructure.Persistence.Configurations;
|
|
|
|
internal sealed class ContentEntryConfiguration : IEntityTypeConfiguration<ContentEntry>
|
|
{
|
|
public void Configure(EntityTypeBuilder<ContentEntry> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("content_entries");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
|
|
builder.Property(entity => entity.EntryKey).HasMaxLength(100);
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.EntryType).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.Icon).HasMaxLength(100);
|
|
builder.Property(entity => entity.Route).HasMaxLength(500);
|
|
builder.Property(entity => entity.Description).HasMaxLength(2000);
|
|
builder.Property(entity => entity.Visibility).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.AccessRules).IsJson("{}");
|
|
builder.Property(entity => entity.LayoutConfig).IsJson("{}");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.EntryKey }).IsUnique();
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.RegionId,
|
|
entity.EntryType,
|
|
entity.IsActive,
|
|
entity.SortOrder
|
|
});
|
|
|
|
builder.HasOne<Region>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.CreatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.UpdatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
}
|
|
}
|
|
|
|
internal sealed class ContentNodeConfiguration : IEntityTypeConfiguration<ContentNode>
|
|
{
|
|
public void Configure(EntityTypeBuilder<ContentNode> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("content_nodes");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
|
|
builder.Property(entity => entity.NodeKey).HasMaxLength(100);
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.NodeType).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.MarkerType).HasNullableSnakeCaseEnum();
|
|
builder.Property(entity => entity.MarkerConfig).IsJson("{}");
|
|
builder.Property(entity => entity.Path).HasColumnType("ltree");
|
|
builder.Property(entity => entity.AccessRules).IsJson("{}");
|
|
builder.Property(entity => entity.Metadata).IsJson("{}");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.EntryId, entity.NodeKey }).IsUnique();
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.EntryId,
|
|
entity.ParentId,
|
|
entity.SortOrder
|
|
});
|
|
builder.HasIndex(entity => entity.Path).HasMethod("gist");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.MarkerType })
|
|
.HasFilter("marker_type is not null");
|
|
builder.ToTable(table =>
|
|
{
|
|
table.HasCheckConstraint("ck_content_nodes_depth", "depth >= 0");
|
|
});
|
|
|
|
builder.HasOne<ContentEntry>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.EntryId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<Region>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<ContentNode>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.ParentId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.CreatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.UpdatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
}
|
|
}
|
|
|
|
internal sealed class QuestionCollectionConfiguration : IEntityTypeConfiguration<QuestionCollection>
|
|
{
|
|
public void Configure(EntityTypeBuilder<QuestionCollection> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("question_collections");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.CollectionType).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.SourceType).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.Filters).IsJson("{}");
|
|
builder.Property(entity => entity.AccessRules).IsJson("{}");
|
|
builder.Property(entity => entity.TotalScore).HasPrecision(8, 2);
|
|
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.Metadata).IsJson("{}");
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.NodeId,
|
|
entity.Status,
|
|
entity.SortOrder
|
|
});
|
|
builder.ToTable(table =>
|
|
{
|
|
table.HasCheckConstraint(
|
|
"ck_question_collections_question_count",
|
|
"question_count >= 0");
|
|
table.HasCheckConstraint(
|
|
"ck_question_collections_duration",
|
|
"duration_minutes is null or duration_minutes > 0");
|
|
});
|
|
|
|
builder.HasOne<Region>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<ContentEntry>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.EntryId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<ContentNode>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.NodeId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<Subject>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.SubjectId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<Category>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.CategoryId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<QuestionBank>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.QuestionBankId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.CreatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.UpdatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
}
|
|
}
|
|
|
|
internal sealed class QuestionCollectionItemConfiguration :
|
|
IEntityTypeConfiguration<QuestionCollectionItem>
|
|
{
|
|
public void Configure(EntityTypeBuilder<QuestionCollectionItem> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("question_collection_items");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.SectionKey).HasMaxLength(100);
|
|
builder.Property(entity => entity.Score).HasPrecision(8, 2);
|
|
builder.Property(entity => entity.Metadata).IsJson("{}");
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.CollectionId,
|
|
entity.QuestionId
|
|
}).IsUnique();
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.CollectionId,
|
|
entity.SectionKey,
|
|
entity.SortOrder
|
|
});
|
|
|
|
builder.HasOne<QuestionCollection>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.CollectionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
builder.HasOne<Question>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.QuestionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
}
|
|
}
|
|
|
|
internal sealed class PracticeBlueprintConfiguration : IEntityTypeConfiguration<PracticeBlueprint>
|
|
{
|
|
public void Configure(EntityTypeBuilder<PracticeBlueprint> builder)
|
|
{
|
|
builder.ConfigureTenantEntity("practice_blueprints");
|
|
builder.ConfigureTimestamps();
|
|
builder.Property(entity => entity.LegacyId).HasMaxLength(64);
|
|
builder.Property(entity => entity.Name).HasMaxLength(300);
|
|
builder.Property(entity => entity.Mode).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.AssemblyType).HasSnakeCaseEnum();
|
|
builder.Property(entity => entity.TotalScore).HasPrecision(8, 2);
|
|
builder.Property(entity => entity.PassScore).HasPrecision(8, 2);
|
|
builder.Property(entity => entity.Sections).IsJson("[]");
|
|
builder.Property(entity => entity.Rules).IsJson("{}");
|
|
builder.Property(entity => entity.AccessRules).IsJson("{}");
|
|
builder.Property(entity => entity.Status).HasSnakeCaseEnum();
|
|
builder.HasIndex(entity => new { entity.TenantId, entity.LegacyId }).IsUnique();
|
|
builder.HasIndex(entity => new
|
|
{
|
|
entity.TenantId,
|
|
entity.NodeId,
|
|
entity.CollectionId,
|
|
entity.Mode,
|
|
entity.Status,
|
|
entity.SortOrder
|
|
});
|
|
builder.ToTable(table =>
|
|
{
|
|
table.HasCheckConstraint(
|
|
"ck_practice_blueprints_question_limit",
|
|
"question_limit is null or question_limit > 0");
|
|
table.HasCheckConstraint(
|
|
"ck_practice_blueprints_duration",
|
|
"duration_minutes is null or duration_minutes > 0");
|
|
});
|
|
|
|
builder.HasOne<Region>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.RegionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<ContentEntry>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.EntryId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<ContentNode>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.NodeId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<QuestionCollection>().WithMany()
|
|
.HasForeignKey(entity => new { entity.TenantId, entity.CollectionId })
|
|
.HasPrincipalKey(entity => new { entity.TenantId, entity.Id })
|
|
.OnDelete(DeleteBehavior.Restrict);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.CreatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
builder.HasOne<User>().WithMany()
|
|
.HasForeignKey(entity => entity.UpdatedBy)
|
|
.OnDelete(DeleteBehavior.SetNull);
|
|
}
|
|
}
|