Aracılığıyla paylaş


Bağlantılı Silme

Entity Framework Core (EF Core), yabancı anahtarları kullanan ilişkileri temsil eder. Yabancı anahtara sahip bir varlık, ilişkideki alt veya bağımlı varlıktır. Bu varlığın yabancı anahtar değeri, ilgili asıl/üst varlığın birincil anahtar değeriyle (veya alternatif anahtar değeriyle) eşleşmelidir.

Asıl/üst varlık silinirse, bağımlı/alt varlıkların yabancı anahtar değerleri artık herhangi bir asıl/üst varlığın birincil veya alternatif anahtarıyla eşleşmez. Bu geçersiz bir durumdur ve çoğu veritabanında bilgi kısıtlama ihlaline neden olur.

Bu bilgi kısıtlaması ihlalini önlemek için iki seçenek vardır:

  1. FK değerlerini null olarak ayarlayın
  2. Ayrıca bağımlı/alt varlıkları da silin

İlk seçenek, yalnızca yabancı anahtar özelliğinin (ve eşlendiği veritabanı sütununun) null değer alabilmesi gereken isteğe bağlı ilişkiler için uygundur.

İkinci seçenek her tür ilişki için geçerlidir ve "art arda silme" olarak bilinir.

Tavsiye

Bu belgede, veritabanını güncelleştirme açısından kaskad silme işlemleri (ve yetimleri silme) ele alınmaktadır. EF Core'da Değişiklik İzleme ve Yabancı Anahtarları ve Gezintileri Değiştirme konularına yönelik kavramları yoğun bir şekilde kullanır. Buradaki malzemeleri ele almadan önce bu kavramları tam olarak anladığınızdan emin olun.

Tavsiye

GitHub'dan örnek kodu indirerek bu belgedeki tüm kodu çalıştırabilir ve hatalarını ayıklayabilirsiniz.

Basamaklı davranışlar gerçekleştiğinde

Bağımlı/alt varlık artık mevcut ana/üst öğesiyle ilişkilendirilemediğinde hiyerarşik silmeler gerekir. Bu durum, sorumlu/üst öğe silindiği veya sorumlu/üst öğe hala mevcutken bağımlı/alt öğenin artık onunla ilişkili olmadığı durumlarda meydana gelebilir.

Ana unsur/ana öğeyi silme

Bu basit modelde Blog, bağımlı/çocuk Post ile ilişkide asıl/ebeveyn unsurudur. Post.BlogId , değeri gönderinin ait olduğu blogun Blog.Id birincil anahtarıyla eşleşmesi gereken yabancı anahtar özelliğidir.

public class Blog
{
    public int Id { get; set; }

    public string Name { get; set; }

    public IList<Post> Posts { get; } = new List<Post>();
}

public class Post
{
    public int Id { get; set; }

    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

Anlaşmaya göre, Post.BlogId yabancı anahtar özelliği null atanamaz olduğundan bu ilişki gerekli olarak yapılandırılır. Gerekli ilişkiler varsayılan olarak art arda silmeleri kullanacak şekilde yapılandırılır. İlişkileri modelleme hakkında daha fazla bilgi için bkz. İlişkiler.

Blog silinirken tüm gönderiler art arda silinir. Örneğin:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

context.Remove(blog);

await context.SaveChangesAsync();

SaveChanges örnek olarak SQL Server kullanarak aşağıdaki SQL'i oluşturur:

-- Executed DbCommand (1ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (2ms) [Parameters=[@p1='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

İlişkiyi kesme

Blogu silmek yerine, her gönderi ile blogu arasındaki ilişkiyi kesebiliriz. Bu, her gönderi için başvuru gezintisi Post.Blog null olarak ayarlanarak yapılabilir:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

foreach (var post in blog.Posts)
{
    post.Blog = null;
}

await context.SaveChangesAsync();

İlişki, koleksiyon gezintisinden Blog.Posts her gönderi kaldırılarak da kesilebilir:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

blog.Posts.Clear();

await context.SaveChangesAsync();

Her iki durumda da sonuç aynıdır: blog silinmez, ancak artık herhangi bir blogla ilişkili olmayan gönderiler silinir:

-- Executed DbCommand (1ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

Artık hiçbir sorumluyla/bağımlıyla ilişkili olmayan varlıkların silinmesi "yalnız bırakılmışları silme" olarak bilinir.

Tavsiye

Zincirleme silme ve yetim kayıtları silme yakından ilişkilidir. Her ikisi de gerekli sorumlu/üst öğeyle ilişki kesildiğinde bağımlı/alt varlıkların silinmesiyle sonuçlanır. Art arda silme için bu kesme işlemi, asıl/üst öğe silindiği için gerçekleşir. Yalnız bırakılmışlar için, asıl/üst varlık hala var, ancak artık bağımlı/alt varlıklarla ilişkili değil.

Basamaklı davranışların gerçekleştiği yer

Basamaklı davranışlar şu değerlere uygulanabilir:

  • DbContext tarafından izlenen varlıklar
  • Veritabanındaki ortama yüklenmemiş varlıklar

İzlenen varlıkları art arda silme

EF Core, izlenen varlıklara her zaman yapılandırılmış basamaklı davranışlar uygular. Bu, uygulama yukarıdaki örneklerde gösterildiği gibi tüm ilgili bağımlı/alt varlıkları DbContext'e yüklerse, veritabanının nasıl yapılandırıldığına bakılmaksızın basamaklı davranışların doğru şekilde uygulanacağı anlamına gelir.

Tavsiye

Basamaklı davranışların izlenen varlıklarda ne zaman gerçekleştiğinin tam zamanlaması, ChangeTracker.CascadeDeleteTiming ve ChangeTracker.DeleteOrphansTiming kullanılarak kontrol edilebilir. Daha fazla bilgi için Yabancı Anahtarlar ve Gezinme Değişiklikleri bölümüne bakın.

Veritabanında kaskad silme

Birçok veritabanı sistemi, veritabanında bir varlık silindiğinde tetiklenen basamaklı davranışlar da sunar. EF Core, EnsureCreated veya EF Core geçişleri kullanılarak bir veritabanı oluşturulduğunda, EF Core modelindeki zincirleme silme davranışına göre bu davranışları yapılandırır. Örneğin, yukarıdaki model kullanılarak, SQL Server kullanılırken gönderiler için aşağıdaki tablo oluşturulur:

CREATE TABLE [Posts] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Content] nvarchar(max) NULL,
    [BlogId] int NOT NULL,
    CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE
);

Bloglar ve gönderiler arasındaki ilişkiyi tanımlayan yabancı anahtar kısıtlamasının ile ON DELETE CASCADEyapılandırıldığına dikkat edin.

Veritabanının bu şekilde yapılandırıldığını biliyorsak, önce gönderileri yüklemeden bir blogu silebiliriz ve veritabanı bu blogla ilgili tüm gönderileri silme işlemini üstlenir. Örneğin:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).FirstAsync();

context.Remove(blog);

await context.SaveChangesAsync();

Postlar için bir Include bulunmadığına dikkat edin, bu yüzden yüklenmiyorlar. Bu durumda SaveChanges yalnızca blogu siler çünkü izlenen tek varlık budur:

-- Executed DbCommand (6ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

Veritabanındaki yabancı anahtar kısıtlaması art arda silme işlemleri için yapılandırılmamışsa bu bir özel durumla sonuçlanır. Ancak bu durumda, oluşturulduğunda ON DELETE CASCADE ile yapılandırıldığı için gönderiler veritabanı tarafından silinir.

Uyarı

Veritabanları genellikle yalnız bırakılmışları otomatik olarak silmek için herhangi bir yönteme sahip değildir. Bunun sebebi, EF Core'un ilişkileri yabancı anahtarların yanı sıra yönlendirmeler kullanarak temsil etmesine karşın, veritabanlarının yalnızca yabancı anahtarlara sahip olması ve yönlendirmelerin bulunmamasıdır. Bu, her iki tarafı da DbContext'e yüklemeden bir ilişkinin kesilmesinin genellikle mümkün olmadığı anlamına gelir.

Uyarı

EF Core bellek içi veritabanı şu anda veritabanında art arda silmeleri desteklemiyor.

Uyarı

Varlıkları geçici olarak silerken veritabanında art arda silmeyi yapılandırmayın. Bu, varlıkların geçici olarak silinmek yerine yanlışlıkla silinmesine neden olabilir.

Veritabanı zincirleme sınırlamaları

Özellikle SQL Server olmak üzere bazı veritabanlarının döngüleri oluşturan art arda davranışlarıyla ilgili sınırlamaları vardır. Örneğin, aşağıdaki modeli göz önünde bulundurun:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public IList<Post> Posts { get; } = new List<Post>();

    public int OwnerId { get; set; }
    public Person Owner { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }

    public int AuthorId { get; set; }
    public Person Author { get; set; }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    public IList<Post> Posts { get; } = new List<Post>();

    public Blog OwnedBlog { get; set; }
}

Bu model, her biri gerekli olan üç ilişkiye sahiptir ve bu nedenle kurala göre bu ilişkilerin art arda silme işlemi yapılandırılmıştır.

  • Blog silindiğinde ilgili tüm gönderiler art arda silinir
  • Gönderilerin yazarının silinmesi, yazılan gönderilerin art arda silinmesine neden olur
  • Blog sahibinin silinmesi, blogun art arda silinmesine neden olur

Bunların tümü makuldür (blog yönetimi ilkeleriyle ilgili biraz katıysa!) ancak bu kaskadlı ayarlara sahip bir SQL Server veritabanı oluşturmaya çalışmak aşağıdaki istisna ile sonuçlanır:

Microsoft.Data.SqlClient.SqlException (0x80131904): 'Postlar' tablosunda 'FK_Posts_Person_AuthorId' FOREIGN KEY kısıtlamasına giriş, döngülere veya birden çok basamaklı yola neden olabilir. ON DELETE NO ACTION veya ON UPDATE NO ACTION belirtin ya da diğer YABANCı ANAHTAR kısıtlamalarını değiştirin.

Bu durumu ele almanın iki yolu vardır:

  1. İlişkilerden birini veya birkaçını art arda silme işlemi olmayacak şekilde değiştirin.
  2. Veritabanını bu art arda silme işlemlerinden biri veya daha fazlası olmadan yapılandırın, ardından EF Core'un basamaklı davranışı gerçekleştirebilmesi için tüm bağımlı varlıkların yüklendiğinden emin olun.

Örneğimizle ilk yaklaşımı benimseyerek blog sonrası ilişkiyi null atanabilir bir yabancı anahtar özelliği vererek isteğe bağlı hale getirebiliriz:

public int? BlogId { get; set; }

İsteğe bağlı bir ilişki, gönderinin blog olmadan var olmasına olanak tanır ve bu da art arda silme işleminin varsayılan olarak yapılandırılmayacağı anlamına gelir. Bu, artık basamaklı eylemlerde bir döngü olmadığı ve veritabanının SQL Server'da hatasız oluşturulabileceği anlamına gelir.

Bunun yerine ikinci yaklaşımı benimsediğimizde, blog sahibi ilişkisinin gerekli olmasını ve art arda silme için yapılandırılmasını sağlayabiliriz, ancak bu yapılandırmanın veritabanı için değil yalnızca izlenen varlıklar için geçerli olmasını sağlayabiliriz:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Blog>()
        .HasOne(e => e.Owner)
        .WithOne(e => e.OwnedBlog)
        .OnDelete(DeleteBehavior.ClientCascade);
}

Şimdi hem bir kişiyi hem de sahip olduğu blogu yüklersek ve ardından kişiyi silersek ne olur?

using var context = new BlogsContext();

var owner = await context.People.SingleAsync(e => e.Name == "ajcvickers");
var blog = await context.Blogs.SingleAsync(e => e.Owner == owner);

context.Remove(owner);

await context.SaveChangesAsync();

EF Core, sahibin silinmesi durumunda blogun da otomatik olarak silinmesini sağlar.

-- Executed DbCommand (8ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (2ms) [Parameters=[@p1='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [People]
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

Ancak, blog sahibi silindiğinde blog yüklenmezse:

using var context = new BlogsContext();

var owner = await context.People.SingleAsync(e => e.Name == "ajcvickers");

context.Remove(owner);

await context.SaveChangesAsync();

Ardından veritabanındaki yabancı anahtar kısıtlamasının ihlali nedeniyle bir özel durum oluşturulur:

Microsoft.Data.SqlClient.SqlException: DELETE deyimi "FK_Blogs_People_OwnerId" REFERANS kısıtlamasıyla çelişti. Çakışma "Scratch" veritabanındaki "dbo.Blogs" adlı tabloda, 'OwnerId' sütununda oluştu. Açıklama sonlandırıldı.

Basamaklı null'lar

İsteğe bağlı ilişkiler null atanabilir veritabanı sütunlarına eşlenebilir yabancı anahtar özelliklerine sahiptir. Bu, geçerli bağlayıcı/üst öğe silindiğinde veya bağımlı/alt öğeden ayrıldığında yabancı anahtar değerinin null olarak ayarlanabileceği anlamına gelir.

Basamaklı davranışlar gerçekleştiğinde,ancak bu kez null atanabilir Post.BlogId yabancı anahtar özelliğiyle temsil edilen isteğe bağlı bir ilişki ile ilgili örneklere tekrar göz atalım:

public int? BlogId { get; set; }

bu yabancı anahtar özelliği, ilgili blog silindiğinde her gönderi için null olarak ayarlanır. Örneğin, öncekiyle aynı olan bu kod:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

context.Remove(blog);

await context.SaveChangesAsync();

SaveChanges çağrıldığında artık aşağıdaki veritabanı güncelleştirmeleriyle sonuçlanacak:

-- Executed DbCommand (2ms) [Parameters=[@p1='1', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p1='2', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

-- Executed DbCommand (1ms) [Parameters=[@p2='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p2;
SELECT @@ROWCOUNT;

Benzer şekilde, yukarıdaki örneklerden biri kullanılarak ilişki kesilirse:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

foreach (var post in blog.Posts)
{
    post.Blog = null;
}

await context.SaveChangesAsync();

Veya:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

blog.Posts.Clear();

await context.SaveChangesAsync();

Ardından SaveChanges çağrıldığında gönderiler null yabancı anahtar değerleriyle güncelleştirilir:

-- Executed DbCommand (2ms) [Parameters=[@p1='1', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p1='2', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

EF Core'un yabancı anahtarları ve gezintileri değerleri değiştikçe nasıl yönettiği hakkında daha fazla bilgi için bkz. Yabancı Anahtarları ve Gezintileri Değiştirme .

Uyarı

Bunun gibi ilişkilerin düzeltilmesi, Entity Framework'ün 2008'deki ilk sürümünden bu yana varsayılan davranışı olmuştur. EF Core'un öncesinde bir adı yoktu ve değiştirilmesi mümkün değildi. Artık bir sonraki bölümde açıklandığı gibi ClientSetNull bilinir.

İsteğe bağlı bir ilişkideki bir sorumlu/üst öğe silindiğinde veritabanları da bunun gibi null değerleri art arda eklemek üzere yapılandırılabilir. Ancak bu, veritabanında art arda silme işlemleri kullanmaktan çok daha az yaygındır. Veritabanında aynı anda art arda silme ve basamaklama null değerlerinin kullanılması, SQL Server kullanılırken neredeyse her zaman ilişki döngülerine neden olur. Basamaklı null değerleri yapılandırma hakkında daha fazla bilgi için sonraki bölüme bakın.

Basamaklı davranışları yapılandırma

Tavsiye

Buraya gelmeden önce yukarıdaki bölümleri okuduğunuzdan emin olun. Yukarıdaki malzeme anlaşılmazsa yapılandırma seçenekleri büyük olasılıkla anlamlı olmayacaktır.

Katmanlı davranışlar, OnDelete yöntemini kullanarak OnModelCreating ilişkisi başına yapılandırılır. Örneğin:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Blog>()
        .HasOne(e => e.Owner)
        .WithOne(e => e.OwnedBlog)
        .OnDelete(DeleteBehavior.ClientCascade);
}

Varlık türleri arasındaki ilişkileri yapılandırma hakkında daha fazla bilgi için bkz. İlişkiler .

OnDelete, kesinlikle kafa karıştırıcı olan DeleteBehavior enum'undan bir değer kabul eder. Bu sabit listesi hem izlenen varlıklarda EF Core'un davranışını hem de şemayı oluşturmak için EF kullanıldığında veritabanında art arda silme yapılandırmasını tanımlar.

Veritabanı şeması üzerindeki etkisi

Aşağıdaki tabloda, EF Core geçişleri veya OnDeletetarafından oluşturulan yabancı anahtar kısıtlaması üzerindeki her EnsureCreated değerin sonucu gösterilmektedir.

SilmeDavranışı Veritabanı şeması üzerindeki etkisi
Şelale SİLMEK ÜZERİNE KASKAD (SQL)
Sınırlamak SİLME KISITLA
EylemYok veritabanı varsayılanı
Null Ayarla SİLİNİNCE NULL OLARAK AYARLA
ClientSetNull veritabanı varsayılanı
ClientCascade veritabanı varsayılanı
MüşteriEylemsiz veritabanı varsayılanı

ON DELETE NO ACTION (veritabanı varsayılanı) ve ON DELETE RESTRICT arasındaki ilişkisel veritabanlarındaki davranışlar genellikle ya aynı ya da çok benzerdir. Her ne kadar NO ACTION ima etse de, bu seçeneklerin her ikisi de başvuru kısıtlamalarının uygulanmasına neden olmaktadır. Aradaki fark, eğer varsa, veritabanının kısıtlamaları ne zaman denetlediğidir. Veritabanı sisteminizdeki ON DELETE NO ACTION ve ON DELETE RESTRICT arasındaki belirli farklar için veritabanı belgelerinize bakınız.

SQL Server desteklemez ON DELETE RESTRICT, bunun ON DELETE NO ACTION yerine kullanılır.

Veritabanında basamaklı davranışlara neden olacak tek değerler Cascade ve SetNull'dir. Diğer tüm değerler, veritabanını herhangi bir değişikliği art arda eklemeyecek şekilde yapılandıracaktır.

SaveChanges davranışı üzerindeki etkisi

Aşağıdaki bölümlerde yer alan tablolar, sorumlu/üst öğe silindiğinde veya bağımlı/alt varlıklarla ilişkisi kesildiğinde bağımlı/alt varlıklara ne olacağını kapsar. Her tablo şunlardan birini kapsar:

  • İsteğe bağlı (null atanabilir yabancı anahtar) ve gerekli (null değeri kabul etmeyen yabancı anahtar) ilişkiler
  • Bağımlılar/alt öğeler DbContext tarafından yüklenip izlendiklerinde ve yalnızca veritabanında mevcut olduklarında

Bağımlılar/çocuklarla gerekli ilişki yüklendi.

SilmeDavranışı Sorumlu/üst öğenin silinmesi hakkında Ana öğeden/baba öğeden kesilme
Şelale EF Core tarafından silinen bağımlılar EF Core tarafından silinen bağımlılar
Sınırlamak InvalidOperationException InvalidOperationException
EylemYok InvalidOperationException InvalidOperationException
Null Ayarla SqlException veritabanı oluştururken SqlException veritabanı oluştururken
ClientSetNull InvalidOperationException InvalidOperationException
ClientCascade EF Core tarafından silinen bağımlılar EF Core tarafından silinen bağımlılar
MüşteriEylemsiz DbUpdateException InvalidOperationException

Notlar:

  • Bunun gibi gerekli ilişkiler için varsayılan değerdir Cascade.
  • Gerekli ilişkiler için zincirleme silme dışında bir yöntem kullanılması, SaveChanges çağrıldığında bir özel durumla karşılaşılmasına neden olur.
    • Genellikle, yüklenen alt öğelerin/bağımlıların geçersiz durumu algılandığında, bu EF Core'dan gelen bir InvalidOperationException durumudur.
    • ClientNoAction, EF Core'u bağımlı düzeltmeleri veritabanına göndermeden önce denetlememeye zorlar, bu nedenle bu durumda veritabanı bir özel durum fırlatır ve SaveChanges tarafından DbUpdateException içinde sarmalanır.
    • SetNull , yabancı anahtar sütunu null atanamaz olduğundan veritabanı oluşturulurken reddedilir.
  • Bağımlılar/alt öğeler yüklendiğinden, bunlar her zaman EF Core tarafından silinir ve veritabanının silinmesi için hiçbir zaman bırakılmaz.

Bağımlılar/çocuklarla gerekli ilişki yüklenmedi

SilmeDavranışı Sorumlu/üst öğenin silinmesi hakkında Ana öğeden/baba öğeden kesilme
Şelale Veritabanı tarafından silinen bağımlılar Mevcut Değil
Sınırlamak DbUpdateException Mevcut Değil
EylemYok DbUpdateException Mevcut Değil
Null Ayarla SqlException veritabanı oluştururken Mevcut Değil
ClientSetNull DbUpdateException Mevcut Değil
ClientCascade DbUpdateException Mevcut Değil
MüşteriEylemsiz DbUpdateException Mevcut Değil

Notlar:

  • Bağımlılar/çocuklar yüklenmediği için burada ilişkilerin kesilmesi geçerli değildir.
  • Bunun gibi gerekli ilişkiler için varsayılan değerdir Cascade.
  • Gerekli ilişkiler için zincirleme silme dışında bir yöntem kullanılması, SaveChanges çağrıldığında bir özel durumla karşılaşılmasına neden olur.
    • DbUpdateException Bunun nedeni genellikle bağımlıların/alt çocukların yüklenmemesidir ve bu nedenle geçersiz durum yalnızca veritabanı tarafından algılanabilir. SaveChanges, veritabanı özel durumunu DbUpdateException içinde sarar.
    • SetNull , yabancı anahtar sütunu null atanamaz olduğundan veritabanı oluşturulurken reddedilir.

Bağımlılar/çocuklar yüklendi, isteğe bağlı ilişki

SilmeDavranışı Sorumlu/üst öğenin silinmesi hakkında Ana öğeden/baba öğeden kesilme
Şelale EF Core tarafından silinen bağımlılar EF Core tarafından silinen bağımlılar
Sınırlamak EF Core tarafından null olarak ayarlanan bağımlı FK'ler EF Core tarafından null olarak ayarlanan bağımlı FK'ler
EylemYok EF Core tarafından null olarak ayarlanan bağımlı FK'ler EF Core tarafından null olarak ayarlanan bağımlı FK'ler
Null Ayarla EF Core tarafından null olarak ayarlanan bağımlı FK'ler EF Core tarafından null olarak ayarlanan bağımlı FK'ler
ClientSetNull EF Core tarafından null olarak ayarlanan bağımlı FK'ler EF Core tarafından null olarak ayarlanan bağımlı FK'ler
ClientCascade EF Core tarafından silinen bağımlılar EF Core tarafından silinen bağımlılar
MüşteriEylemsiz DbUpdateException EF Core tarafından null olarak ayarlanan bağımlı FK'ler

Notlar:

  • Bunun gibi isteğe bağlı ilişkiler için varsayılan değerdir ClientSetNull.
  • Bağımlılar/çocuklar, Cascade ve ClientCascade yapılandırılmadıkça hiçbir zaman silinmez.
  • Diğer tüm değerler, ef core tarafından bağımlı FK'lerin null olarak ayarlanmasına neden olur...
    • ...ancak ClientNoAction, sorumlu/üst öğe silindiğinde EF Core'a, bağımlıların/çocukların yabancı anahtarlarına dokunmamasını söyler. Bu nedenle veritabanı, DbUpdateException özel durumunu fırlatır ve SaveChanges tarafından sarılır.

Bakmakla yükümlü olunan kişiler/çocuklarla isteğe bağlı ilişki yüklenmedi

SilmeDavranışı Sorumlu/üst öğenin silinmesi hakkında Ana öğeden/baba öğeden kesilme
Şelale Veritabanı tarafından silinen bağımlılar Mevcut Değil
Sınırlamak DbUpdateException Mevcut Değil
EylemYok DbUpdateException Mevcut Değil
Null Ayarla Bağımlı FK'ler veritabanına göre null olarak ayarlanmış Mevcut Değil
ClientSetNull DbUpdateException Mevcut Değil
ClientCascade DbUpdateException Mevcut Değil
MüşteriEylemsiz DbUpdateException Mevcut Değil

Notlar:

  • Bağımlılar/çocuklar yüklenmediği için burada ilişkilerin kesilmesi geçerli değildir.
  • Bunun gibi isteğe bağlı ilişkiler için varsayılan değerdir ClientSetNull.
  • Veritabanı, silmeleri veya null atamaları zincirleme şekilde gerçekleştirecek biçimde yapılandırılmadığı sürece, veritabanı hatasını önlemek için bağımlılar/çocuklar yüklenmelidir.