Entity Framework'ü veritabanından her zaman güncellenmiş verileri almaya nasıl zorlayabilirim?


91

Toplu güncellemeleri gerçekleştirmek için EntityFramework.Extended kitaplığı kullanıyorum . Tek sorun, EF'in kitaplık tarafından gerçekleştirilen toplu güncellemeleri takip etmemesidir. Bu yüzden DbContexttekrar sorguladığımda güncellenmiş varlıkları döndürmüyor.

AsNoTracking()Sorgulama sırasında yöntemi kullanmanın izlemeyi devre dışı bıraktığını ve veritabanından yeni veriler aldığını buldum . Bununla birlikte, EF sorgulanan varlıkları takip etmediğinden AsNoTracking(), sorgulanan veriler üzerinde herhangi bir güncelleme yapamıyorum.

Değişiklikleri izlerken EF'i en son verileri almaya zorlamanın bir yolu var mı?


2
Bu konuda 29k görüş ve sadece 19 upvotes ... şey, ben yine mayın ekledi
jleach

Yanıtlar:


152

Lütfen tek bir varlığı yenilemek için şunu deneyin:

Context.Entry<T>(entity).Reload()

Düzenleme: Bir varlık koleksiyonu için yeni veriler elde etmek, DbContexther istekten sonra örneği elden çıkarmaya değer .


Teşekkür ederim! Bir varlık koleksiyonunu bir yerine yeniden yüklemenin bir yolu var mı? Tercihen tamamı DbSet.
Saravana

Bunun yanıt olarak kabul edilmesi için ihtiyacınız olan başka bir şey var mı?
PlTaylor

1
Evet, bir varlık koleksiyonunun nasıl yeniden yükleneceğini hala göstermiyor.
Saravana

1
Dbcontext'inizi atmayı ve yeni bir tane oluşturmayı denediniz mi?
PlTaylor

3
Bu sonuca varmam saatlerimi aldı. Yanıttaki DÜZENLEME , çözümümü bulmama yardımcı olan şeydi. Teşekkürler!
BeemerGuy

17

Varlığı güncelledikten sonra navigasyon özelliklerinin doldurulmadığı bir soruna bir çözüm ararken bu soruya rastladım. Varlığı veritabanından yeniden yüklemeye çalıştığımda, girişi yerel depodan kapacak ve bunun yerine gezinti özelliklerini tembel yükleme yoluyla doldurmayacaktı. Bağlamı bozup yeniden oluşturmak yerine, bunun çalışan proxy'ler ile yeni veriler elde etmeme izin verdiğini gördüm:

_db.Entry(entity).State = EntityState.Detached;

Bunun arkasındaki mantık şuydu - güncellemem varlığa eklenen değişiklikleri takip edebilsin. Bu, onu yerel mağazaya ekler. Bundan sonra, işlevsel vekilleri olan varlığı geri getirme girişimleri, veritabanına gitmek ve yeni, vekil etkin bir varlık döndürmek yerine yerel olanı yakalamasına neden olacaktır. Nesneyi veritabanından yenileyen yukarıdaki yeniden yükleme seçeneğini denedim, ancak bu size tembel yüklemeli proxy nesnesini vermiyor. Yapmayı denedim Find(id), Where(t => t.Id = id), First(t => t.Id = id). Son olarak, sağlanan mevcut durumları kontrol ettim ve "Ayrılmış" bir durum olduğunu gördüm. Eureka! Umarım bu birine yardımcı olur.


Yavaş yüklemenin çalışmasını sağlamak için Ayrılmış durumu nereye uyguluyorsunuz lütfen? Çözümünüzü denedim ve benim için işe yaramadı, bir şeyi kaçırmış olmalıyım. Yardımınız minnettar olacaktır
Rex

2
Anladım: 1. varlığı kaydedin, 2. durumu ayrılmış olarak ayarlayın, 3. varlığı db'den okuyun. İpucu için teşekkürler!
Rex

1

Kodun aynı bağlamda çalıştırılması, size güncellenmiş varlıklar vermez. Yalnızca çalıştırmalar arasında veritabanında oluşturulan yeni varlıkları ekler. EF zorla yeniden yükleme şu şekilde yapılabilir:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();

1

Varlık değişkenini atamasız, sınıfın bir parçası olarak tanımladım. Bu, diğer yöntemlerle referans için değişkeni kaybetmeden bir örneği elden çıkarmamı sağladı. Bununla yeni karşılaştım, bu yüzden kemerinin altında çok fazla çalışma süresi yok, ama şimdiye kadar iyi çalışıyor gibi görünüyor.

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}

0

Benim için ... DbContext'ime şu şekilde erişiyorum:

_viewModel.Repo.Context

EF'yi veritabanına vurmaya zorlamak için şunu yapıyorum:

_viewModel.Repo.Context = new NewDispatchContext();

Yeni bir örnekle mevcut DbContext'in üzerine yazma. Daha sonra veri servislerimi bir dahaki sefer kullandığımda verileri veritabanından alıyorlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.