次のエンティティモデルを検討してください。
public class Agreement : Entity
{
public int AgreementId { get; set; }
public virtual ICollection<Participant> Participants { get; set; }
}
public class Establishment : Entity
{
public int EstablishmentId { get; set; }
}
public class Participant : Entity
{
public int AgreementId { get; set; }
public virtual Agreement Agreement { get; set; }
public int EstablishmentId { get; set; }
public virtual Establishment { get; set; }
public bool IsOwner { get; set; }
}
契約エンティティに直接がない理由はICollection<Establishment>
、この多対多の関係をさらに定義するIsOwnerプロパティのためです。
関係は次のようにマップされます。
internal ParticipantOrm()
{
ToTable(typeof(Participant).Name);
HasKey(k => new { k.AgreementId, k.EstablishmentId });
HasRequired(d => d.Agreement)
.WithMany(p => p.Participants)
.HasForeignKey(d => d.AgreementId)
.WillCascadeOnDelete(true);
HasRequired(d => d.Establishment)
.WithMany()
.HasForeignKey(d => d.EstablishmentId)
.WillCascadeOnDelete(true);
}
関係は一方向です。つまり、契約内からのみ参加者にアクセスできます。つまり、施設から契約にアクセスすることはできません。
さて、契約エンティティの主キーは動名詞参加者の主キーの一部であり、カスケード削除が指定されているため、契約を削除済み状態にすると、参加者コレクション内の各エンティティも削除された状態。
これは、AgreementDbSetでRemoveを呼び出すときに機能するようです。
// this works
dbContext.Agreements.Remove(agreement);
dbContext.SaveChanges();
ただし、単に契約エントリの状態を削除に設定した場合は機能しないようです。
// this causes an exception when Participants is not empty
dbContext.Entry(agreement).State = EntityState.Deleted;
dbContext.SaveChanges();
契約エンティティを削除状態にするだけで、対応するコレクションアイテムエンティティも削除状態になるように、関係を定義する方法はありますか?
アップデート
私はこれについて読んでいて、参加者コレクションを熱心にロードしても役に立たないことがわかりました。
// eager loading does not help, this still breaks
var agreement = dbContext.Set<Agreement>()
.Include(a => a.Participants)
.FirstOrDefault();
dbContext.Entry(agreement).State = EntityState.Deleted;
dbContext.SaveChanges();