Saya sudah bergumul dengan hal ini untuk sementara waktu dan tidak tahu apa yang terjadi. Saya memiliki entitas Kartu yang mengandung Sisi (biasanya 2) - dan kedua Kartu dan Sisi memiliki Panggung. Saya menggunakan migrasi EF Codefirst dan migrasi gagal dengan kesalahan ini:
Memperkenalkan kendala KUNCI ASING 'FK_dbo.Sides_dbo.Cards_CardId' pada tabel 'Sisi' dapat menyebabkan siklus atau beberapa jalur kaskade. Tentukan HAPUS TANPA TINDAKAN atau DIPERBARUI TANPA TINDAKAN, atau ubah batasan KUNCI ASING lainnya.
Inilah entitas Kartu saya :
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; }
}
Ini milik saya entitas sisi :
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; }
}
Dan ini milik saya entitas Panggung :
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; } }
}
Apa yang aneh adalah bahwa jika saya menambahkan yang berikut ke kelas Stage saya:
public int? SideId { get; set; }
[ForeignKey("SideId")]
public virtual Side Side { get; set; }
Migrasi berjalan dengan sukses. Jika saya membuka SSMS dan melihat tabel, saya bisa melihatnyaStage_StageId
telah ditambahkan ke Cards
(seperti yang diharapkan / diinginkan), namun Sides
tidak mengandung referensi ke Stage
(tidak diharapkan).
Jika saya tambahkan
[Required]
[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int StageId { get; set; }
Untuk kelas sampingku, begitu StageId
kolom ditambahkan ke Side
meja saya .
Ini berfungsi, tetapi sekarang di seluruh aplikasi saya, referensi apa pun yang Stage
mengandung SideId
, yang dalam beberapa kasus sama sekali tidak relevan. Saya ingin memberikan properti Card
dan Side
entitas saya Stage
berdasarkan kelas Stage di atas tanpa mencemari kelas stage dengan properti referensi jika memungkinkan ... apa yang saya lakukan salah?
Side
Class tambahkan integer Nullable dan hapus[Required]
atribut =>public int? CardId { get; set; }
DeleteBehavior.Restrict
atauDeleteBehavior.SetNull
.Jawaban:
Karena
Stage
yang diperlukan , semua hubungan satu-ke-banyak manaStage
yang terlibat akan memiliki Cascading menghapus diaktifkan secara default. Artinya, jika Anda menghapus suatuStage
entitasSide
Card
dan karenaCard
danSide
memiliki hubungan satu-ke-banyak yang diperlukan dengan penghapusan kaskade diaktifkan secara default lagi maka kaskade akan mengalir dariCard
keSide
Jadi, Anda memiliki dua path penghapusan cascading dari
Stage
keSide
- yang menyebabkan pengecualian.Anda harus membuat
Stage
opsional setidaknya di salah satu entitas (yaitu menghapus[Required]
atribut dariStage
properti) atau menonaktifkan penghapusan cascading dengan Fluent API (tidak mungkin dengan anotasi data):sumber
Stage
. Hubungan lainnya tetap tidak berubah.Stage
penghapusan turun keSide
langsung dan melaluiCard
Saya punya meja yang memiliki hubungan melingkar dengan orang lain dan saya mendapatkan kesalahan yang sama. Ternyata ini tentang kunci asing yang tidak dapat dibatalkan. Jika kunci tidak dapat dibatalkan, obyek terkait harus dihapus dan relasi melingkar tidak mengizinkannya. Jadi gunakan kunci asing yang dapat dibatalkan.
sumber
int?
alih-alihint
membiarkannya menjadi nol.Siapa pun yang bertanya-tanya bagaimana melakukannya di inti EF:
sumber
builder.HasOne(x => x.Stage).WithMany().HasForeignKey(x => x.StageId).OnDelete(DeleteBehavior.Restrict);
builder _ .Entity<TEntity>() _
sebelumnyaHasOne()
dapat dipanggil ...IEntityTypeConfiguration<T>
. Saya tidak ingat melihatbuilder.Entity<T>
metode itu hari itu, tetapi saya bisa saja salah. Meskipun demikian, keduanya akan bekerja :)Saya mendapatkan kesalahan ini untuk banyak entitas ketika saya bermigrasi dari model EF7 ke versi EF6. Saya tidak ingin harus melalui setiap entitas satu per satu, jadi saya menggunakan:
sumber
Anda dapat mengatur cascadeDelete ke false atau true (dalam migrasi Anda metode Up ()). Tergantung pada kebutuhan Anda.
sumber
UP
metode ini dapat dimodifikasi oleh operasi eksternal.Di .NET Core saya mengubah opsi onDelete menjadi ReferencialAction.NoAction
sumber
Saya memiliki masalah ini juga, saya langsung menyelesaikannya dengan jawaban ini dari utas yang sama
Dalam kasus saya, saya tidak ingin menghapus catatan tergantung pada penghapusan kunci. Jika hal ini terjadi dalam situasi Anda, cukup ubah nilai Boolean dalam migrasi menjadi false:
Kemungkinannya adalah, jika Anda membuat hubungan yang membuat kesalahan kompiler ini tetapi DO ingin mempertahankan cascade delete; Anda memiliki masalah dengan hubungan Anda.
sumber
Saya memperbaiki ini. Saat Anda menambahkan migrasi, dalam metode Naik () akan ada baris seperti ini:
Jika Anda hanya menghapus cascadeDelete dari akhir itu akan berhasil.
sumber
Hanya untuk keperluan dokumentasi, untuk seseorang yang datang di masa depan, hal ini dapat diselesaikan sesederhana ini, dan dengan metode ini, Anda dapat melakukan metode yang dinonaktifkan satu kali, dan Anda dapat mengakses metode Anda secara normal
Tambahkan metode ini ke kelas basis data konteks:
sumber
Ini terdengar aneh dan saya tidak tahu mengapa, tetapi dalam kasus saya itu terjadi karena ConnectionString saya menggunakan "." dalam atribut "sumber data". Setelah saya mengubahnya menjadi "localhost" itu bekerja seperti pesona. Tidak ada perubahan lain yang diperlukan.
sumber
Dalam .NET Core saya bermain dengan semua jawaban atas - tetapi tanpa hasil. Saya membuat banyak perubahan dalam struktur DB dan setiap kali menambahkan upaya migrasi baru
update-database
, tetapi menerima kesalahan yang sama.Kemudian saya mulai
remove-migration
satu per satu sampai Package Manager Console memberi saya pengecualian:Setelah itu, saya menambahkan migrasi baru (
add-migration
) danupdate-database
berhasilJadi saran saya adalah: hapus semua migrasi temporer Anda, hingga status DB Anda saat ini.
sumber
Jawaban yang ada sangat bagus. Saya hanya ingin menambahkan bahwa saya mengalami kesalahan ini karena alasan yang berbeda. Saya ingin membuat migrasi EF awal pada DB yang sudah ada tetapi saya tidak menggunakan -IgnoreChanges flag dan menerapkan perintah Update-Database pada Database yang kosong (juga gagal yang ada).
Sebaliknya saya harus menjalankan perintah ini ketika struktur db saat ini adalah yang sekarang:
Mungkin ada masalah nyata dalam struktur db tetapi menyelamatkan dunia selangkah demi selangkah ...
sumber
Cara sederhana adalah dengan, Sunting berkas migrasi
(cascadeDelete: true)
ke(cascadeDelete: false)
kemudian setelah menetapkan perintah Update-Database di Anda Package Manager Console.if masalah itu dengan migrasi terakhir Anda kemudian kanan semua. Kalau tidak, periksa riwayat migrasi Anda sebelumnya, salin hal-hal itu, tempel ke file migrasi terakhir Anda, setelah itu lakukan hal yang sama. itu sangat cocok untuk saya.sumber
Ketika migrasi Anda gagal, Anda diberikan beberapa opsi: 'Memperkenalkan kendala KUNCI ASING' FK_dbo.Rekomendasi Book_dbo.Department_DepartmentID 'pada tabel' RecommendedBook 'dapat menyebabkan siklus atau beberapa jalur kaskade. Tentukan HAPUS TANPA TINDAKAN atau DIPERBARUI TANPA TINDAKAN, atau ubah batasan KUNCI ASING lainnya. Tidak dapat membuat batasan atau indeks. Lihat kesalahan sebelumnya. '
Berikut adalah contoh penggunaan 'modifikasi batasan ASE lainnya' dengan menetapkan 'cascadeDelete' menjadi false dalam file migrasi dan kemudian jalankan 'update-database'.
sumber
Tidak ada solusi yang disebutkan di atas yang berhasil untuk saya. Apa yang harus saya lakukan adalah menggunakan int nullable (int?) Pada kunci asing yang tidak diperlukan (atau bukan kunci kolom bukan nol) dan kemudian menghapus beberapa migrasi saya.
Mulai dengan menghapus migrasi, lalu coba int nullable.
Masalahnya adalah modifikasi dan desain model. Tidak diperlukan perubahan kode.
sumber
Buat atribut kunci Asing Anda nullable. Itu akan bekerja.
sumber