46 lines
1.9 KiB
C#
46 lines
1.9 KiB
C#
using BlueLaminate.EFCore.Entities;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||
|
||
namespace BlueLaminate.EFCore.Configurations;
|
||
|
||
public class SkinConfiguration : IEntityTypeConfiguration<Skin>
|
||
{
|
||
public void Configure(EntityTypeBuilder<Skin> entity)
|
||
{
|
||
// Nullable: null means the catalogue gives no wear range (e.g. vanilla
|
||
// knives), distinct from a genuine 0.0–1.0 range.
|
||
entity.Property(e => e.FloatMin).HasColumnType("numeric(10,9)");
|
||
entity.Property(e => e.FloatMax).HasColumnType("numeric(10,9)");
|
||
|
||
entity.Property(e => e.TrueFloat)
|
||
.HasComputedColumnSql("float_min = 0.0 AND float_max = 1.0", stored: true);
|
||
|
||
entity.HasIndex(e => e.TrueFloat);
|
||
|
||
// Slug is the natural key the sync upserts against.
|
||
entity.HasIndex(e => e.Slug).IsUnique();
|
||
|
||
// Market listings join back to a skin by (def_index, paint_index). Unique
|
||
// among populated rows; filtered so the many catalogue rows that predate
|
||
// these columns (null) don't collide. Postgres treats nulls as distinct
|
||
// anyway, but the filter makes the intent explicit and the index smaller.
|
||
entity.HasIndex(e => new { e.DefIndex, e.PaintIndex })
|
||
.IsUnique()
|
||
.HasFilter("def_index IS NOT NULL AND paint_index IS NOT NULL");
|
||
|
||
// Per-site "last swept" checkpoints live in skin_sweeps (one row per site);
|
||
// see SkinSweepConfiguration for the indexes that order them.
|
||
|
||
entity.HasOne(e => e.Weapon)
|
||
.WithMany(w => w.Skins)
|
||
.HasForeignKey(e => e.WeaponId);
|
||
|
||
// A skin can come from many collections and containers, and each of those
|
||
// holds many skins.
|
||
entity.HasMany(e => e.Collections)
|
||
.WithMany(c => c.Skins)
|
||
.UsingEntity(join => join.ToTable("skin_collections"));
|
||
}
|
||
}
|