Entity Framework Yenileme bağlamı?


101

Bağlamımı nasıl yenileyebilirim? Veritabanımdaki görünümlere dayalı varlıklarım var ve görünümler için gezinme özelliklerine sahip bir tablo Varlığı üzerinde güncelleme yaptığımda varlık güncelleniyor ancak görünüm yeni güncellemelere göre yenilenmiyor ... sadece tekrar almak istiyorum Db verileri. Teşekkürler!

Yanıtlar:


92

Bağlamınızdaki varlıkları yenilemenin en iyi yolu, bağlamınızı elden çıkarmak ve yeni bir tane oluşturmaktır.

Eğer varsa gerçekten bazı varlık yenilemek gerekiyor ve DBContext sınıfıyla Kod İlk yaklaşım kullanarak, sen kullanabilirsiniz

    public static void ReloadEntity<TEntity>(
        this DbContext context, 
        TEntity entity)
        where TEntity : class
    {
        context.Entry(entity).Reload();
    }

Koleksiyon gezinme özelliklerini yeniden yüklemek için şunu kullanabilirsiniz:

    public static void ReloadNavigationProperty<TEntity, TElement>(
        this DbContext context, 
        TEntity entity, 
        Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
        where TEntity : class
        where TElement : class
    {
        context.Entry(entity).Collection<TElement>(navigationProperty).Query();
    }

Başvuru: https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx#M:System.Data.Entity.Infrastructure.DbEntityEntry .Tekrar yükle


3
Bunun alt gezinme özelliklerini yeniden yüklemek için çalışmasını sağlayamıyorum.
Paul

@David context.ReloadNavigationProperty(parent, p => p.Children);eğer varsa kullanabilirsinclass Parent { ICollection<Child> Children; }
Jinjinov

EF Core'da Query (). Load () kullanabilirsiniz, örneğincontext.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
Rubenisme

Bu çözümün neden bu kadar yüksek oy aldığını anlamıyorum. context.Entry (entity) .Collection <TElement> (navigationProperty) .Query (), alt koleksiyonu yeniden yüklemez. Yalnızca koleksiyonu almak için kullanılan sorguyu temsil eden bir Iqueryable verir. Kelimenin tam anlamıyla hiçbir şey yapmaz.
statler

72
yourContext.Entry(yourEntity).Reload();

3
Kolay çözüm için teşekkürler. Bunu RX_DID_RX'in yaptığı gibi bir uzatma yönteminde kapsüllemenin gerekliliğini görmüyorum
Thomas

Bu benim için bir cankurtarandı. Teşekkür ederim!
Kevin

19
Bunun koleksiyon gezinme özelliklerini yeniden yüklemediğini, yalnızca varlık girişinin kendisini yeniden yüklediğini unutmayın.
James Wilkins

28

Belirli varlıkları DbContextApi ile yeniden yüklemek istiyorsanız, RX_DID_RX size zaten cevabı verdi.

Yüklediğiniz tüm varlıkları yeniden yüklemek / yenilemek istiyorsanız:

Entity Framework 4.1+ (muhtemelen EF5 veya EF 6) kullanıyorsanız, DbContext API:

public void RefreshAll()
{
     foreach (var entity in ctx.ChangeTracker.Entries())
     {
           entity.Reload();
     }
}

EntityFramework 4 (ObjectContext API) kullanıyorsanız:

public void RefreshAll()
{
     // Get all objects in statemanager with entityKey
     // (context.Refresh will throw an exception otherwise)
     var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted
                                               | EntityState.Modified
                                               | EntityState.Unchanged)
                                      where entry.EntityKey != null
                                      select entry.Entity);

     context.Refresh(RefreshMode.StoreWins, refreshableObjects);
}

Yine de en iyi tavsiye, "kısa ömürlü bir bağlam" kullanmaya çalışın ve bu tür sorunlardan kaçınmanızdır.

Konuyla ilgili birkaç makale yazdım:

https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/


güzel!! Günümü kurtardım!
Radu D

16

Yenileme yöntemini kullanın :

context.Refresh(RefreshMode.StoreWins, yourEntity);

veya alternatif olarak mevcut bağlamınızı atın ve yeni bir tane oluşturun.


@JMK Burada tam olarak ne çalışmıyor? Benim için iyi çalışıyor gibi görünüyor (EF 6.1.1).
Sebastian Krysmanski

@SebastianKrysmanski Yaklaşık bir yıl önce yorum yapmıştım, belki o zamandan beri düzeltildi?
JMK

5
Sadece nesne bağlamı için çalıştığını, dbcontext için çalışmadığını düşünüyorum. Aralarında bir konuşma yapılması gerekiyor
Emil

3
@batmaci Hangisi ile kolayca yapılabilir((IObjectContextAdapter)dbContext).ObjectContext
Daniel

3
Bu da biraz eksik belirtilmedi.
user441521

6

bağlam.Reload () MVC 4, EF 5'te benim için çalışmıyordu, bu yüzden bunu yaptım.

context.Entry(entity).State = EntityState.Detached;
entity = context.Find(entity.ID);

ve iyi çalışıyor.


1

EF 6

Benim senaryomda, Entity Framework yeni güncellenen verileri almıyordu. Bunun nedeni, verilerin kapsamının dışında güncellenmiş olması olabilir. Getirdikten sonra verileri yenilemek sorunumu çözdü.

private void RefreshData(DBEntity entity)
{
    if (entity == null) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entity);
}

private void RefreshData(List<DBEntity> entities)
{
    if (entities == null || entities.Count == 0) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entities);
}

1
EF6'danım. Bu neden a'dan daha iyi _context.Entry(entity).Reload();?
Csaba Toth

Hatırlayabildiğim kadarıyla .Reload()EF6'da yok. @CsabaToth
Mahbubur Rahman

0

Yeniden yükleme ile db bağlamının yenilenmesi, performans kayıpları nedeniyle tavsiye edilmez. Her işlem yürütülmeden önce dbcontext'in yeni bir örneğini başlatmak yeterince iyidir ve en iyi uygulamadır. Ayrıca, her işlem için size yenilenmiş güncel bir bağlam sağlar.

using (YourContext ctx = new YourContext())
{
   //Your operations
}

6
Dostum .. Her seferinde bağlamınızı boşa çıkarmak istemediğiniz şeylerin yenilenmesini de sağlayacak, bu da gerçekten Performans Sorunlarına yol açacaktır.
LuckyLikey

3
Bu, birim testleri yazma becerisini etkilediği için korkunç bir fikirdir. Kodunuz patlarsa ve yeni bir bağlamda haber verirse, bu bir birim testi sırasında nasıl çalışacak?
victor

5
Eleştiri yapmak yerine bazı örnekler göstermeniz benim ve diğerleri için faydalı olacaktır.
aog

Küçük web siteleri için gayet iyi.
alikuli

-1

Aslında şunu yapmanı öneririm, kodumda bu kod form oluşturuyor ve veri tabanında veriyi yenile iptal et düğmesine bastıktan sonra diyalog olarak göster

NewJobOrder newJobOrder = new NewJobOrder();
    newJobOrder.ShowDialog();
    if (newJobOrder.DialogResult == DialogResult.Cancel)
    {
        this.jobOrderTableAdapter.Fill(this.multiTechDBDataSet.JobOrder);
        }

Eh, burada bir bağlam bile yok. Bu, tamamen farklı bir teknoloji olan bir veri kümesini doldurmakla ilgilidir. Sorudaki sorunu nasıl ele alacağınızı bilmiyorsanız, neden yanıtı kaldırmıyorsunuz? Cevabınızın ilk versiyonunda aynı tartışmayı yaptığımızı hatırlıyorum.
Gert Arnold

-7

Kendi başımı hiç acıtmadım! Cevap çok basitti - sadece temellere döndüm ...

some_Entities   e2 = new some_Entities(); //your entity.

Bu satırı güncelledikten / sildikten sonra aşağıya ekleyin - varlığınızı yeniden yüklüyorsunuz - süslü sistem yöntemleri yok.

e2 = new some_Entities(); //reset.

3
Bu "işe yarayacak" - bu sadece korkunç bir fikir ve başka sonuçları olacak
Adam Hey
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.