fix data model
This commit is contained in:
parent
e2c594f68d
commit
8669a0124c
|
|
@ -14,6 +14,7 @@ public class DayConfiguration : IEntityTypeConfiguration<Day>
|
|||
{
|
||||
public void Configure(EntityTypeBuilder<Day> builder)
|
||||
{
|
||||
|
||||
builder.ToTable("Days");
|
||||
|
||||
builder.HasKey(x => x.Id);
|
||||
|
|
@ -25,26 +26,24 @@ public class DayConfiguration : IEntityTypeConfiguration<Day>
|
|||
.HasConversion<int>()
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.ClubId).IsRequired();
|
||||
builder.Property(x => x.ClubId)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasOne(x => x.Club)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ClubId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
|
||||
// DayConfiguration: Relation Day -> DayPerson über (DayId, ClubId)
|
||||
builder.HasMany(d => d.DayPersons)
|
||||
.WithOne(dp => dp.Day)
|
||||
.HasForeignKey(dp => new { dp.DayId, dp.ClubId })
|
||||
.HasPrincipalKey(d => new { d.Id, d.ClubId });
|
||||
|
||||
|
||||
// Wichtig für DayPerson-Composite FK: Alternate Key (Id, ClubId)
|
||||
// Alternate Key für DayPerson-Composite FK: (Id, ClubId)
|
||||
builder.HasAlternateKey(x => new { x.Id, x.ClubId });
|
||||
|
||||
builder.HasIndex(x => new { x.ClubId, x.PostDate });
|
||||
|
||||
builder.HasQueryFilter(x => !x.IsDeleted);
|
||||
|
||||
// Wichtig:
|
||||
// Keine HasMany(x => x.DayPersons) hier definieren, weil die Club-Konsistenz
|
||||
// via Composite-FK in DayPersonConfiguration abgebildet wird.
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ public class ExpenseConfiguration : IEntityTypeConfiguration<Expense>
|
|||
|
||||
builder.HasKey(x => x.Id);
|
||||
|
||||
builder.Property(x => x.ClubId).IsRequired();
|
||||
builder.Property(x => x.ClubId)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.Name)
|
||||
.HasMaxLength(200)
|
||||
|
|
@ -43,9 +44,13 @@ public class ExpenseConfiguration : IEntityTypeConfiguration<Expense>
|
|||
.HasForeignKey(x => x.ClubId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// Alternate Key für Composite-FK in ExpenseTrigger: (Id, ClubId)
|
||||
builder.HasAlternateKey(x => new { x.Id, x.ClubId });
|
||||
|
||||
builder.HasIndex(x => x.ClubId);
|
||||
|
||||
builder.HasQueryFilter(x => !x.IsDeleted);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,22 +14,30 @@ public class ExpenseTriggerConfiguration : IEntityTypeConfiguration<ExpenseTrigg
|
|||
{
|
||||
public void Configure(EntityTypeBuilder<ExpenseTrigger> builder)
|
||||
{
|
||||
|
||||
builder.ToTable("ExpenseTriggers");
|
||||
|
||||
// Eine aktive Zuordnung pro Club/Expense/Trigger
|
||||
builder.HasKey(x => new { x.ClubId, x.ExpenseId, x.TriggerId });
|
||||
|
||||
builder.Property(x => x.AssignedAt).IsRequired();
|
||||
builder.Property(x => x.AssignedById).IsRequired();
|
||||
builder.Property(x => x.AssignedAt)
|
||||
.IsRequired()
|
||||
.HasDefaultValueSql("SYSUTCDATETIME()");
|
||||
|
||||
builder.Property(x => x.AssignedById)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasOne(x => x.Club)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ClubId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// WICHTIG: Club-Konsistenz erzwingen:
|
||||
// (ExpenseId, ClubId) muss in Expense (Id, ClubId) existieren
|
||||
builder.HasOne(x => x.Expense)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ExpenseId)
|
||||
.HasForeignKey(x => new { x.ExpenseId, x.ClubId })
|
||||
.HasPrincipalKey(e => new { e.Id, e.ClubId })
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(x => x.Trigger)
|
||||
|
|
@ -39,6 +47,8 @@ public class ExpenseTriggerConfiguration : IEntityTypeConfiguration<ExpenseTrigg
|
|||
|
||||
builder.HasIndex(x => x.ExpenseId);
|
||||
builder.HasIndex(x => x.TriggerId);
|
||||
builder.HasIndex(x => x.ClubId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ public class PersonConfiguration : IEntityTypeConfiguration<Person>
|
|||
{
|
||||
public void Configure(EntityTypeBuilder<Person> builder)
|
||||
{
|
||||
|
||||
builder.ToTable("Persons");
|
||||
|
||||
builder.HasKey(x => x.Id);
|
||||
|
|
@ -21,14 +22,15 @@ public class PersonConfiguration : IEntityTypeConfiguration<Person>
|
|||
.HasConversion<int>()
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.ClubId).IsRequired();
|
||||
builder.Property(x => x.ClubId)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasOne(x => x.Club)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ClubId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// Wichtig für DayPerson-Composite FK: Alternate Key (Id, ClubId)
|
||||
// Alternate Key für DayPerson-Composite FK: (Id, ClubId)
|
||||
builder.HasAlternateKey(x => new { x.Id, x.ClubId });
|
||||
|
||||
builder.HasMany(x => x.Expenses)
|
||||
|
|
@ -36,16 +38,13 @@ public class PersonConfiguration : IEntityTypeConfiguration<Person>
|
|||
.HasForeignKey(x => x.PersonId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
// PersonConfiguration: Relation Person -> DayPerson über (PersonId, ClubId)
|
||||
builder.HasMany(p => p.DayPersons)
|
||||
.WithOne(dp => dp.Person)
|
||||
.HasForeignKey(dp => new { dp.PersonId, dp.ClubId })
|
||||
.HasPrincipalKey(p => new { p.Id, p.ClubId });
|
||||
|
||||
|
||||
builder.HasIndex(x => x.ClubId);
|
||||
|
||||
builder.HasQueryFilter(x => !x.IsDeleted);
|
||||
|
||||
// Wichtig:
|
||||
// Keine HasMany(x => x.DayPersons) hier definieren, weil die Club-Konsistenz
|
||||
// via Composite-FK in DayPersonConfiguration abgebildet wird.
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,32 +13,40 @@ public class UserProfileClubConfiguration : IEntityTypeConfiguration<UserProfile
|
|||
{
|
||||
public void Configure(EntityTypeBuilder<UserProfileClub> builder)
|
||||
{
|
||||
|
||||
builder.ToTable("UserProfileClubs");
|
||||
|
||||
// 1 Zuordnung pro (UserProfile, Club)
|
||||
builder.HasKey(x => new { x.UserProfileId, x.ClubId });
|
||||
|
||||
|
||||
builder.Property(x => x.AssignedAt).IsRequired();
|
||||
builder.Property(x => x.AssignedById).IsRequired();
|
||||
// optional default
|
||||
builder.Property(x => x.AssignedAt).HasDefaultValueSql("SYSUTCDATETIME()");
|
||||
|
||||
|
||||
builder.HasOne(x => x.Club)
|
||||
.WithMany() // oder: Club.UserProfiles wenn du das als Navigation ergänzt
|
||||
.HasForeignKey(x => x.ClubId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
// Beziehung zu UserProfile (fehlte)
|
||||
builder.HasOne(x => x.UserProfile)
|
||||
.WithMany(x => x.Clubs)
|
||||
.HasForeignKey(x => x.UserProfileId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Beziehung zu Club
|
||||
builder.HasOne(x => x.Club)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ClubId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Optional: nur einen Default-Club je Profil erzwingen (SQL Server: filtered index)
|
||||
builder.Property(x => x.IsDefault)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.AssignedAt)
|
||||
.IsRequired()
|
||||
.HasDefaultValueSql("SYSUTCDATETIME()");
|
||||
|
||||
builder.Property(x => x.AssignedById)
|
||||
.IsRequired();
|
||||
|
||||
// SQL Server: pro UserProfile nur EIN Default-Club
|
||||
builder.HasIndex(x => x.UserProfileId)
|
||||
.HasFilter("[IsDefault] = 1")
|
||||
.IsUnique();
|
||||
|
||||
builder.HasIndex(x => x.ClubId);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using System.Reflection;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Koogle.Infrastrcuture
|
||||
namespace Koogle.Infrastructure
|
||||
{
|
||||
public static class DependencyInjection
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue