1

EF コードの最初のデータベースにいくつかの変更を加えました。更新しようとすると、次のエラーが発生します。

テーブル 'SupportTicketMessages' に FOREIGN KEY 制約 'FK_dbo.SupportTicketMessages_dbo.SupportTickets_Ticket_Id' を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります。ON DELETE NO ACTION または ON UPDATE NO ACTION を指定するか、他の FOREIGN KEY 制約を変更します。

ここに私のエンティティがあります:

サポートチケット:

public class SupportTicket
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        public string Title { get; set; }

        [Required]
        public string Text { get; set; }

        [Required]
        public TicketUrgency Urgency { get; set; }

        [Required]
        public TicketStatus Status { get; set; }

        [Required]
        public virtual UserProfile Owner { get; set; }

        [Required]
        public DateTime Date { get; set; }
}

サポートチケットメッセージ:

public class SupportTicketMessage
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        public virtual UserProfile Author { get; set; }

        [Required]
        public string Text { get; set; }

        [Required]
        public DateTime Date { get; set; }

        [Required]
        public virtual SupportTicket Ticket { get; set; }

        [Required]
        public int MessageNumber { get; set; }
    }

ここで何が問題なのですか?何が悪いのかわかりません。

4

1 に答える 1

2

UserProfile両方のエンティティで問題が必要です。

と の間に3 つの必要な1 対多の関係がUserProfileありSupportTicketます SupportTicketMessage

  1. 1 UserProfile- 多くSupportTicketの s
  2. 1 UserProfile- 多くSupportTicketMessageの s
  3. 1 SupportTicket- 多くSupportTicketMessageの s

(左側はプリンシパル (関係の主キーを持つ) であり、右側は従属 (関係の外部キーを持つ) です)。

必要な 1 対多の関係の場合、EF はデフォルトでカスケード削除をデータベースに追加します。つまり、上の左側のエンティティが削除されると、右側のすべての依存エンティティが自動的に削除されます。

今すぐ削除する場合、テーブルUserProfileへの 2 つのカスケード削除パスがあります。つまり、次のとおりです。SupportTicketMessage

  • UserProfile-> SupportTicket-> SupportTicketMessage(関係 1 と 3 のため)
  • UserProfile-> SupportTicketMessage(関係 2 のため)

これは SQL Server では許可されておらず、例外の理由です。

この問題を解決するには、関係の少なくとも 1 つのカスケード削除パスを「解除」する必要があります。これを行うには、リレーションシップをオプションにする (つまり、ナビゲーション プロパティの属性の 1 つを[Required]削除する) か、カスケード削除を明示的に無効にします。リレーションシップを必須からオプションに変更することはビジネス ルールを変更するようなものであるため、後者のオプションを選択します。リレーションシップ 1 と 2 のカスケード削除を無効にします。おそらく、aUserProfileを削除してもすべてSupportTicketの とSupportTicketMessageが削除されるのではなく、代わりにチケットとメッセージを「匿名の」デフォルト ユーザーに割り当てて、チケットの履歴が失われないようにする必要があるからです。ユーザーがシステムを離れたいとき。

Fluent API でカスケード削除を無効にする必要があります。

modelBuilder.Entity<SupportTicket>()
    .HasRequired(s => s.Owner)
    .WithMany()
    .WillCascadeOnDelete(false);

modelBuilder.Entity<SupportTicketMessage>()
    .HasRequired(s => s.Author)
    .WithMany()
    .WillCascadeOnDelete(false);

( s およびs をUserProfile参照するナビゲーション コレクションがある場合は、 および のように、ラムダ パラメーターを指定して呼び出しを使用する必要があります。)SupportTicketSupportTicketMessageWithManyWithMany(u => u.SupportTickets)WithMany(u => u.SupportTicketMessages)

于 2013-08-10T13:15:19.737 に答える