Pertanyaan DbSet.Attach (entitas) vs DbContext.Entry (entitas) .State = EntityState.Modified


Ketika saya berada dalam skenario terpisah dan mendapatkan dto dari klien yang saya petakan ke entitas untuk menyimpannya saya melakukan ini:

context.Entry(entity).State = EntityState.Modified;
context.SaveChanges();

Untuk apa itu DbSet.Attach(entity)

atau mengapa saya harus menggunakan metode .Attach ketika EntityState.Modified sudah melampirkan entitas?


76
2018-06-22 19:03


asal


Jawaban:


Saat kamu melakukan context.Entry(entity).State = EntityState.Modified;, Anda tidak hanya melampirkan entitas ke DbContext, Anda juga menandai seluruh entitas sebagai kotor. Ini berarti ketika Anda melakukannya context.SaveChanges(), EF akan menghasilkan pernyataan pembaruan yang akan diperbarui semua bidang entitas.

Ini tidak selalu diinginkan.

Di samping itu, DbSet.Attach(entity) melekatkan entitas ke konteks tanpa menandainya kotor. Ini setara dengan melakukan context.Entry(entity).State = EntityState.Unchanged;

Ketika melampirkan cara ini, kecuali Anda kemudian melanjutkan untuk memperbarui properti pada entitas, waktu berikutnya Anda menelepon context.SaveChanges(), EF tidak akan menghasilkan pembaruan basis data untuk entitas ini.

Bahkan jika Anda berencana melakukan pembaruan ke suatu entitas, jika entitas tersebut memiliki banyak properti (kolom db) tetapi Anda hanya ingin memperbarui beberapa, Anda mungkin merasa menguntungkan untuk melakukan DbSet.Attach(entity), dan kemudian hanya memperbarui beberapa properti yang perlu diperbarui. Melakukannya dengan cara ini akan menghasilkan pernyataan pembaruan yang lebih efisien dari EF. EF hanya akan memperbarui properti yang Anda modifikasi (berbeda dengan context.Entry(entity).State = EntityState.Modified; yang akan menyebabkan semua properti / kolom diperbarui)

Dokumentasi yang relevan: Add / Attach and Entity States.

Contoh kode

Katakanlah Anda memiliki entitas berikut:

public class Person
{
    public int Id { get; set; } // primary key
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Jika kode Anda terlihat seperti ini:

context.Entry(personEntity).State = EntityState.Modified;
context.SaveChanges();

SQL yang dihasilkan akan terlihat seperti ini:

UPDATE person
SET FirstName = 'whatever first name is',
    LastName = 'whatever last name is'
WHERE Id = 123; -- whatever Id is.

Perhatikan bagaimana pernyataan pembaruan di atas akan memperbarui semua kolom, terlepas atau apakah Anda benar-benar mengubah nilainya atau tidak.

Sebaliknya, jika kode Anda menggunakan "normal" Lampirkan seperti ini:

context.People.Attach(personEntity); // State = Unchanged
personEntity.FirstName = "John"; // State = Modified, and only the FirstName property is dirty.
context.SaveChanges();

Maka pernyataan pembaruan yang dihasilkan berbeda:

UPDATE person
SET FirstName = 'John'
WHERE Id = 123; -- whatever Id is.

Seperti yang Anda lihat, pernyataan pembaruan hanya memperbarui nilai yang benar-benar berubah setelah Anda melekatkan entitas ke konteks. Tergantung pada struktur meja Anda, ini dapat memiliki dampak kinerja positif.

Sekarang, opsi mana yang lebih baik untuk Anda bergantung sepenuhnya pada apa yang Anda coba lakukan.


184
2018-06-22 19:24



Saat Anda menggunakan DbSet.Update metode, Entity Framework menandai semua properti dari entitas Anda sebagai EntityState.Modified, melacaknya. Jika Anda ingin mengubah hanya beberapa properti Anda, tidak semuanya, gunakan DbSet.Attach. Metode ini membuat semua properti Anda EntityState.Unchanged, jadi Anda harus membuat properti yang ingin Anda perbarui EntityState.Modified. Dengan demikian ketika aplikasi hits DbContext.SaveChanges, itu hanya akan mengoperasikan properti yang dimodifikasi.


0
2017-09-15 07:27