次のエンティティ定義があります。
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
必要がありますMembers
。Group
にメンバーがない場合、それはサブグループを含む親グループである必要があり、そのすべてに少なくとも1 つのメンバーが含まれている必要があります。事実上、サブグループのメンバーは親グループによって継承されるべきです (ただし、概念的にのみ、親グループは実際のメンバーを失うべきです) - 非親には少なくとも 1 つのメンバーが含まれている
Group
必要があります
では、これを検証するにはどうすればよいでしょうか。メンバーのないすべてのグループを検索し、それぞれにサブグループが「含まれている」かどうかを確認し、親グループ以外のグループになるまで、各サブグループに対して同じチェックを再帰的に実行する必要があります。この時点で、各グループがメンバーが含まれています。
これをエレガントに行う方法がわかりません。おそらく正しくないコードを何時間も見つめたり、円を描いて書いたりリファクタリングしたりして忘却に陥り、数分ごとに頭を壁にぶつけたりする代わりに、StackOverflow であるシンクタンクの助けを借りることにしました。:)
再帰は進むべき道ですか、それともより良い代替手段はありますか? 前もって感謝します。