2

次のエンティティ定義があります。

public class Member
{
  [Key] public int Id { get; set; }
  [Required] public string Name { get; set; }

  [Required] public ICollection<Group> Groups { get; set; } // Must be a member of at least one group
}

public class Group
{
  [Key] public int Id { get; set; }
  [Required] public string Name { get; set; }

  public int? ParentGroupId { get; set; }
  public Group ParentGroup { get; set; }

  public ICollection<Member> Members { get; set; } // Must contain at least one member (unless it contains subgroups - see below)
}

Fluent マッピング構成:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Many-to-Many Group <--> Member
    modelBuilder.Entity<Group>()
      .HasMany(g => g.Members)
      .WithMany(m => m.Groups)
      .Map(map =>
            {
              map.ToTable("GroupMembers");
              map.MapLeftKey("GroupId");
              map.MapRightKey("MemberId");
            });

    // Self-referencing Group to allow for hierarchy of groups
    modelBuilder.Entity<Group>()
      .HasOptional(g => g.ParentGroup)
      .WithMany()
      .HasForeignKey(pg => pg.ParentGroupId);
}

検証規則は次のとおりです。

  • Aは少なくとも 1 つに属しているMember 必要がありますGroup
  • を含めるGroup 必要がありますMembersGroupにメンバーがない場合、それはサブグループを含む親グループである必要があり、そのすべてに少なくとも1 つのメンバーが含まれている必要があります。事実上、サブグループのメンバーは親グループによって継承されるべきです (ただし、概念的にのみ、親グループは実際のメンバーを失うべきです)
  • 非親には少なくとも 1 つのメンバーが含まれているGroup 必要があります

では、これを検証するにはどうすればよいでしょうか。メンバーのないすべてのグループを検索し、それぞれにサブグループが「含まれている」かどうかを確認し、親グループ以外のグループになるまで、各サブグループに対して同じチェックを再帰的に実行する必要があります。この時点で、各グループがメンバーが含まれています。

これをエレガントに行う方法がわかりません。おそらく正しくないコードを何時間も見つめたり、円を描いて書いたりリファクタリングしたりして忘却に陥り、数分ごとに頭を壁にぶつけたりする代わりに、StackOverflow であるシンクタンクの助けを借りることにしました。:)

再帰は進むべき道ですか、それともより良い代替手段はありますか? 前もって感謝します。

4

0 に答える 0