私はしばらくこの問題に取り組んできましたが、何が起こっているのかよくわかりません。私は Sides (通常 2) を含む Card エンティティを持っています。そして、Cards と Sides の両方に Stage があります。私は EF Codefirst 移行を使用していますが、移行は次のエラーで失敗します:
テーブル 'Sides' に FOREIGN KEY 制約 'FK_dbo.Sides_dbo.Cards_CardId' を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります。ON DELETE NO ACTION または ON UPDATE NO ACTION を指定するか、他の FOREIGN KEY 制約を変更してください。
これが私のカードエンティティです:
public class Card
{
public Card()
{
Sides = new Collection<Side>();
Stage = Stage.ONE;
}
[Key]
[Required]
public virtual int CardId { get; set; }
[Required]
public virtual Stage Stage { get; set; }
[Required]
[ForeignKey("CardId")]
public virtual ICollection<Side> Sides { get; set; }
}
これが私のサイドエンティティです:
public class Side
{
public Side()
{
Stage = Stage.ONE;
}
[Key]
[Required]
public virtual int SideId { get; set; }
[Required]
public virtual Stage Stage { get; set; }
[Required]
public int CardId { get; set; }
[ForeignKey("CardId")]
public virtual Card Card { get; set; }
}
そして、これが私のステージエンティティです:
public class Stage
{
// Zero
public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE");
// Ten seconds
public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO");
public static IEnumerable<Stage> Values
{
get
{
yield return ONE;
yield return TWO;
}
}
public int StageId { get; set; }
private readonly TimeSpan span;
public string Title { get; set; }
Stage(TimeSpan span, string title)
{
this.span = span;
this.Title = title;
}
public TimeSpan Span { get { return span; } }
}
奇妙なのは、Stage クラスに次のコードを追加すると次のようになることです。
public int? SideId { get; set; }
[ForeignKey("SideId")]
public virtual Side Side { get; set; }
Stage_StageId
移行は正常に実行されます。SSMS を開いてテーブルを確認すると、が追加されていることがわかりますCards
(予想どおり/希望どおり)。ただし、Sides
への参照は含まれていませんStage
(予想外)。
次に
[Required]
[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int StageId { get; set; }
サイドクラスでは、テーブルStageId
に列が追加されていることがわかりますSide
。
これは機能していますが、アプリケーション全体で、 への参照に がStage
含まれておりSideId
、これは場合によってはまったく無関係です。可能であれば、ステージ クラスを参照プロパティで汚染することなく、およびエンティティに上記のステージ クラスに基づくプロパティを与えたいのですCard
Side
Stage
が...何が間違っているのでしょうか?
ベストアンサー1
Stage
が必須であるため、 が関係するすべての1対多関係ではStage
連鎖削除がデフォルトで有効になります。つまり、Stage
エンティティを削除すると
- 削除は直接カスケードされます
Side
- 削除は に直接カスケードします
Card
。 とCard
はSide
必須の1対多の関係を持ち、カスケード削除がデフォルトで有効になっているため、 から にカスケードしますCard
。Side
Stage
したがって、からへの 2 つのカスケード削除パスがありSide
、例外が発生します。
Stage
少なくとも 1 つのエンティティでオプションにする (つまり、プロパティ[Required]
から属性を削除するStage
) か、Fluent API を使用してカスケード削除を無効にする (データ注釈では不可能)必要があります。
modelBuilder.Entity<Card>()
.HasRequired(c => c.Stage)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Side>()
.HasRequired(s => s.Stage)
.WithMany()
.WillCascadeOnDelete(false);