Aracılığıyla paylaş


Varlık durumlarıyla çalışma

Bu konu başlığında, bir bağlama varlık ekleme ve ekleme ve Entity Framework'ün Bunları SaveChanges sırasında işleme şekli ele alınacaktır. Entity Framework, bir bağlama bağlıyken varlıkların durumunun izlenmesini sağlar, ancak bağlantısı kesilmiş veya N Katmanlı senaryolarda EF'ye varlıklarınızın hangi durumda olması gerektiğini bildirebilirsiniz. Bu konu başlığında gösterilen teknikler, gerek Code First gerekse EF Designer ile oluşturulan modellere için geçerlidir.

Varlık durumları ve SaveChanges

Varlık, EntityState numaralandırması tarafından tanımlanan beş durumdan birinde olabilir. Bu durumlar şunlardır:

  • Eklendi: Varlık bağlam tarafından izleniyor ancak henüz veritabanında yok
  • Değişmedi: varlık bağlam tarafından izleniyor ve veritabanında var ve özellik değerleri veritabanındaki değerlerden değişmedi
  • Değiştirildi: Varlık bağlam tarafından izleniyor ve veritabanında var ve özellik değerlerinin bir kısmı veya tümü değiştirildi
  • Silindi: Varlık bağlam tarafından izleniyor ve veritabanında var, ancak SaveChanges bir sonraki çağrılışında veritabanından silinmek üzere işaretlendi
  • Ayrılmış: Varlık bağlam tarafından izlenmiyor

SaveChanges, farklı durumlardaki varlıklar için farklı şeyler yapar:

  • Değişmeyen varlıklara SaveChanges tarafından dokunulmaz. Güncelleştirmeler, Değişmemiş durumundaki varlıklar için veritabanına gönderilmez.
  • Eklenen varlıklar veritabanına eklenir ve SaveChanges döndürdüğünde Değişmedi olur.
  • Değiştirilen varlıklar veritabanında güncelleştirilir ve SaveChanges döndürdüğünde Değişmedi olur.
  • Silinen varlıklar veritabanından silinir ve ardından bağlamdan ayrılır.

Aşağıdaki örneklerde bir varlığın veya varlık grafiğinin durumunun değiştirilebileceği yollar gösterilmektedir.

Bağlama yeni bir varlık ekleme

DbSet'te Add yöntemi çağrılarak bağlama yeni bir varlık eklenebilir. Bu, varlığı Eklendi durumuna getirir; yani SaveChanges bir sonraki çağrılışında veritabanına eklenir. Örnek:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Blogs.Add(blog);
    context.SaveChanges();
}

Bağlama yeni bir varlık eklemenin bir diğer yolu da durumunu Eklendi olarak değiştirmektir. Örnek:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Entry(blog).State = EntityState.Added;
    context.SaveChanges();
}

Son olarak, zaten izlenmekte olan başka bir varlığa bağlayarak bağlama yeni bir varlık ekleyebilirsiniz. Bu, yeni varlığı başka bir varlığın koleksiyon gezinti özelliğine ekleyerek veya başka bir varlığın başvuru gezinti özelliğini yeni varlığa işaret etmek üzere ayarlayarak olabilir. Örnek:

using (var context = new BloggingContext())
{
    // Add a new User by setting a reference from a tracked Blog
    var blog = context.Blogs.Find(1);
    blog.Owner = new User { UserName = "johndoe1987" };

    // Add a new Post by adding to the collection of a tracked Blog
    blog.Posts.Add(new Post { Name = "How to Add Entities" });

    context.SaveChanges();
}

Eklenen varlığın henüz izlenmemiş diğer varlıklara başvuruları varsa, bu örneklerin tümü için bu yeni varlıkların bağlama da ekleneceğini ve SaveChanges'in bir sonraki çağrılışında veritabanına ekleneceğini unutmayın.

Var olan bir varlığı bağlama ekleme

Veritabanında zaten var olduğunu bildiğiniz ancak bağlam tarafından şu anda izlenmediğini bildiğiniz bir varlığınız varsa, DbSet'teki Attach yöntemini kullanarak varlığı izlemek için bağlamı söyleyebilirsiniz. Varlık, bağlamda Değişmedi durumunda olacaktır. Örnek:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);

    // Do some more work...  

    context.SaveChanges();
}

Ekli varlığın başka bir düzenlemesi yapılmadan SaveChanges çağrılırsa veritabanında hiçbir değişiklik yapılmayacağını unutmayın. Bunun nedeni varlığın Değişmemiş durumunda olmasıdır.

Var olan bir varlığı bağlama eklemenin başka bir yolu da durumunu Değişmedi olarak değiştirmektir. Örnek:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Bu örneklerin her ikisi için de, eklenen varlığın henüz izlenmeyen diğer varlıklara başvuruları varsa, bu yeni varlıkların da Değişmemiş durumundaki bağlama eklendiğini unutmayın.

Var olan ama değiştirilen bir varlığı bağlama ekleme

Veritabanında zaten var olduğunu bildiğiniz ancak değişikliklerin yapılmış olabileceğini bildiğiniz bir varlığınız varsa, varlığın eklenmesi için bağlamı söyleyebilir ve durumunu Değiştirildi olarak ayarlayabilirsiniz. Örnek:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;

    // Do some more work...  

    context.SaveChanges();
}

Durumu Değiştirildi olarak değiştirdiğinizde varlığın tüm özellikleri değiştirildi olarak işaretlenir ve SaveChanges çağrıldığında tüm özellik değerleri veritabanına gönderilir.

Ekli olan varlığın henüz izlenmeyen diğer varlıklara başvuruları varsa, bu yeni varlıkların değişmemiş durumdaki bağlama eklendiğini unutmayın; bunlar otomatik olarak Değiştirilmez. Değiştirildi olarak işaretlenmesi gereken birden çok varlığınız varsa, bu varlıkların her biri için durumu ayrı ayrı ayarlamanız gerekir.

İzlenen varlığın durumunu değiştirme

Zaten izlenmekte olan bir varlığın durumunu, girdisinde State özelliğini ayarlayarak değiştirebilirsiniz. Örnek:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Zaten izlenen bir varlık için Ekle veya Ekle çağrısının varlık durumunu değiştirmek için de kullanılabileceğini unutmayın. Örneğin, şu anda Eklendi durumunda olan bir varlık için Ekle çağrısı, durumunu Değişmedi olarak değiştirir.

Desen ekleme veya güncelleştirme

Bazı uygulamalar için yaygın olarak kullanılan desenlerden biri, birincil anahtarın değerine bağlı olarak Yeni varlık ekleme (veritabanı ekleme sonucu) veya Var olan bir varlık ekleme ve değiştirilmiş olarak işaretlemektir (veritabanı güncelleştirmesi ile sonuçlanır). Örneğin, veritabanı tarafından oluşturulan tamsayı birincil anahtarları kullanılırken, sıfır anahtar içeren bir varlığa yeni ve sıfır olmayan anahtara sahip bir varlığa mevcut olarak davranılır. Bu düzen, birincil anahtar değerinin denetimine göre varlık durumu ayarlanarak gerçekleştirilebilir. Örnek:

public void InsertOrUpdate(Blog blog)
{
    using (var context = new BloggingContext())
    {
        context.Entry(blog).State = blog.BlogId == 0 ?
                                   EntityState.Added :
                                   EntityState.Modified;

        context.SaveChanges();
    }
}

Durumu Değiştirildi olarak değiştirdiğinizde varlığın tüm özelliklerinin değiştirilmiş olarak işaretleneceğini ve SaveChanges çağrıldığında tüm özellik değerlerinin veritabanına gönderileceğini unutmayın.