Verileri Kaydetme

Sorgulama veritabanından veri okumanıza olanak sağlarken, verileri kaydetmek veritabanına yeni varlıklar eklemek, varlıkları kaldırmak veya mevcut varlıkların özelliklerini bir şekilde değiştirmek anlamına gelir. Entity Framework Core (EF Core), verileri veritabanına kaydetmeye yönelik iki temel yaklaşımı destekler.

Yaklaşım 1: değişiklik izleme ve SaveChanges

Birçok senaryoda, programınızın veritabanındaki bazı verileri sorgulaması, üzerinde bazı değişiklikler yapması ve bu değişiklikleri geri kaydetmesi gerekir; bu bazen "çalışma birimi" olarak adlandırılır. Örneğin, bir dizi Blog'unuza sahip olduğunuzu ve bunlardan birinin özelliğini değiştirmek Url istediğinizi varsayalım. EF'te bu genellikle aşağıdaki gibi yapılır:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Single(b => b.Url == "http://example.com");
    blog.Url = "http://example.com/blog";
    context.SaveChanges();
}

Yukarıdaki kod aşağıdaki adımları gerçekleştirir:

  1. Veritabanından bir varlık yüklemek için normal bir LINQ sorgusu kullanır (bkz . Sorgu verileri). EF'nin sorguları varsayılan olarak izlenir; yani EF, iç değişiklik izleyicisindeki yüklü varlıkları izler.
  2. Yüklenen varlık örneği, bir .NET özelliği atanarak her zamanki gibi değiştirilir. EF bu adıma dahil değildir.
  3. Son olarak, DbContext.SaveChanges() çağrılır. Bu noktada EF, varlıkları yüklendikleri andan itibaren bir anlık görüntüyle karşılaştırarak değişiklikleri otomatik olarak algılar. Algılanan değişiklikler veritabanında kalıcı hale gelir; ilişkisel veritabanı kullanılırken, bu genellikle ilgili satırları güncelleştirmek için sql UPDATE göndermeyi içerir.

Yukarıdaki bölümde mevcut veriler için tipik bir güncelleştirme işlemi açıklanmıştır, ancak benzer ilkelerin varlık ekleme ve kaldırma için de geçerli olduğunu unutmayın. ve Removeçağrısı DbSet<TEntity>.Add yaparak EF'nin değişiklik izleyicisiyle etkileşim kurarsınız ve bu da değişikliklerin izlenmesine neden olur. EF, çağrıldığında SaveChanges() (örneğin SQL INSERT aracılığıyla ve DELETE ilişkisel veritabanı kullanırken) veritabanına izlenen tüm değişiklikleri uygular.

SaveChanges() aşağıdaki avantajları sunar:

  • Hangi varlıkların ve özelliklerin değiştiğini izlemek için kod yazmanız gerekmez. EF bunu sizin için otomatik olarak yapar ve yalnızca veritabanındaki bu özellikleri güncelleştirerek performansı artırır. Yüklenen varlıklarınızın kullanıcı arabirimi bileşenine bağlı olup olmadığını ve kullanıcıların istedikleri özelliği değiştirmesine izin verilip veremediğini düşünün; EF, gerçekte hangi varlıkların ve özelliklerin değiştirildiğini anlama yükünü ortadan kaldırır.
  • Değişiklikleri veritabanına kaydetmek bazen karmaşık olabilir! Örneğin, bu blog için bir Blog ve bazı Gönderiler eklemek istiyorsanız, Gönderileri ekleyebilmeniz için önce eklenen Blog için veritabanı tarafından oluşturulan anahtarı getirmeniz gerekebilir (bloga başvurmaları gerektiğinden). EF tüm bunları sizin için yapar ve karmaşıklığı ortadan kaldırır.
  • EF, sorgunuz ile SaveChanges()arasında bir veritabanı satırının başka biri tarafından değiştirildiği durumlar gibi eşzamanlılık sorunlarını algılayabilir. Eşzamanlılık çakışmalarında daha fazla ayrıntı sağlanır.
  • Bunu destekleyen veritabanlarında, SaveChanges() bir işlemdeki birden çok değişikliği otomatik olarak sarmalar ve bir hata oluştuğunda verilerinizin tutarlı kalmasını sağlar. İşlemler bölümünde daha fazla ayrıntı bulabilirsiniz.
  • SaveChanges() ayrıca birçok durumda birden çok değişikliği toplu işleyerek veritabanı gidiş dönüş sayısını önemli ölçüde azaltır ve performansı büyük ölçüde geliştirir. Daha ayrıntılı bilgi için bkz . Verimli güncelleştirme.

Temel SaveChanges() kullanım hakkında daha fazla bilgi ve kod örnekleri için bkz . Temel SaveChanges. EF'nin değişiklik izlemesi hakkında daha fazla bilgi için bkz . Değişiklik izlemeye genel bakış.

Yaklaşım 2: ExecuteUpdate ve ExecuteDelete ("toplu güncelleştirme")

Dekont

Bu özellik EF Core 7.0'da kullanıma sunulmuştur.

Değişiklik izleme ve SaveChanges() değişiklikleri kaydetmenin güçlü bir yolu olsa da, bazı dezavantajları vardır.

İlk olarak, SaveChanges() değiştireceğiniz veya sileceğiniz tüm varlıkları sorgulamanızı ve izlemenizi gerektirir. Derecelendirmesi belirli bir eşiğin altında olan tüm Blogları silmeniz gerekiyorsa, çok fazla sayıda satırı sorgulamanız, gerçekleştirmeniz ve izlemeniz ve her biri için bir DELETE deyim oluşturmanız gerekirSaveChanges(). İlişkisel veritabanları çok daha verimli bir alternatif sağlar: tek bir DELETE komut gönderilebilir ve bir WHERE yan tümce aracılığıyla hangi satırların silineceğini belirtebilir, ancak SaveChanges() model bunu oluşturmaya izin vermez.

Bu "toplu güncelleştirme" senaryosını desteklemek için aşağıdaki gibi kullanabilirsiniz ExecuteDelete :

context.Blogs.Where(b => b.Rating < 3).ExecuteDelete();

Bu, normal LINQ sorgusuna benzer şekilde normal LINQ işleçleri aracılığıyla sql DELETE deyimini ifade etmenizi sağlar ve bu da veritabanında aşağıdaki SQL'in yürütülmesine neden olur:

DELETE FROM [b]
FROM [Blogs] AS [b]
WHERE [b].[Rating] < 3

Bu, veritabanından veri yüklemeden veya EF'nin değişiklik izleyicisini içermeden veritabanında çok verimli bir şekilde yürütülür. Benzer şekilde, ExecuteUpdate bir SQL UPDATE deyimini ifade etmenizi sağlar.

Varlıkları toplu olarak değiştirmeseniz bile, hangi varlığın özelliklerini değiştirmek istediğinizi tam olarak biliyor olabilirsiniz. Değişikliği gerçekleştirmek için değişiklik izleme API'sini kullanmak aşırı karmaşık olabilir; varlık örneği oluşturma, aracılığıyla Attachizleme, değişikliklerinizi yapma ve son olarak çağrısı SaveChanges()yapma. Bu tür senaryolar ExecuteUpdate için ve ExecuteDelete aynı işlemi ifade etmenin çok daha basit bir yolu olabilir.

Son olarak, hem değişiklik izleme hem SaveChanges() de kendisi belirli bir çalışma zamanı yükü getirir. Yüksek performanslı bir uygulama ExecuteUpdate yazıyorsanız ve bu bileşenlerden kaçınmanıza ve ExecuteDelete istediğiniz deyimi verimli bir şekilde oluşturmanıza izin verirseniz.

Ancak ve'nin ExecuteDelete belirli sınırlamaları olduğunu ExecuteUpdate unutmayın:

  • Bu yöntemler hemen yürütülür ve şu anda diğer işlemlerle toplu işlenemez. Öte yandan , SaveChanges()birden çok işlemi birlikte toplu işleyebilir.
  • Değişiklik izleme söz konusu olmadığından, tam olarak hangi varlıkların ve özelliklerin değiştirilmesi gerektiğini bilmek sizin sorumluluğunuzdadır. Bu, değiştirilmesi gerekenleri ve değişmeyenleri daha el ile ve düşük düzeyli kod izleme anlamına gelebilir.
  • Buna ek olarak, değişiklik izleme söz konusu olmadığından, bu yöntemler değişiklikleri kalıcı hale getirirken Eşzamanlılık Denetimi'ne otomatik olarak uygulanmaz. Ancak, eşzamanlılık denetimini kendiniz uygulamak için yine de açıkça bir Where yan tümce ekleyebilirsiniz.
  • Şu anda yalnızca güncelleştirme ve silme desteklenmektedir; ekleme işlemi ve SaveChanges()aracılığıyla DbSet<TEntity>.Add yapılmalıdır.

Daha fazla bilgi ve kod örnekleri için bkz ExecuteUpdate . ve ExecuteDelete.

Özet

Hangi yaklaşımın ne zaman kullanılacağına ilişkin birkaç yönerge aşağıdadır. Bunların mutlak kurallar olmadığını, ancak yararlı bir temel kurallar sağladığını unutmayın:

  • Hangi değişikliklerin gerçekleştirileceğini önceden bilmiyorsanız kullanın SaveChanges; hangi değişikliklerin uygulanması gerektiğini otomatik olarak algılar. Örnek senaryolar:
    • "Veritabanından bir Blog yüklemek ve kullanıcının değiştirmesine izin veren bir form görüntülemek istiyorum"
  • Bir nesne grafını (birbirine bağlı birden çok nesne) işlemeniz gerekiyorsa kullanın SaveChanges; değişikliklerin doğru sıralanması ve her şeyin birbirine nasıl bağlanacağını belirler.
    • "Blogu güncelleştirmek, bazı gönderilerini değiştirmek ve diğerlerini silmek istiyorum"
  • Bazı ölçütlere göre çok sayıda varlığı değiştirmek istiyorsanız ve ExecuteDeletekullanınExecuteUpdate. Örnek senaryolar:
    • "Tüm çalışanlara zam yapmak istiyorum"
    • "Adı X ile başlayan tüm blogları silmek istiyorum"
  • Hangi varlıkları değiştirmek istediğinizi ve bunları nasıl değiştirmek istediğinizi zaten biliyorsanız ve ExecuteDeletekullanınExecuteUpdate. Örnek senaryolar:
    • "Adı 'Foo' olan blogu silmek istiyorum"
    • "Kimlik 5 olan blogun adını 'Bar' olarak değiştirmek istiyorum"