Kerangka Entitas Segarkan konteks?

101

Bagaimana cara menyegarkan konteks saya? Saya memiliki entitas berdasarkan tampilan dari Database saya dan ketika saya membuat pembaruan atas satu tabel Entitas yang memiliki properti navigasi ke tampilan, entitas diperbarui tetapi tampilan tidak menyegarkan sesuai pembaruan baru ... hanya ingin mendapatkan lagi dari data Db. Terima kasih!

pengguna2528557
sumber

Jawaban:

92

Cara terbaik untuk menyegarkan entitas dalam konteks Anda adalah dengan membuang konteks Anda dan membuat yang baru.

Jika Anda benar - benar perlu menyegarkan beberapa entitas dan Anda menggunakan pendekatan Code First dengan kelas DbContext, Anda dapat menggunakan

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

Untuk memuat ulang properti navigasi koleksi, Anda dapat menggunakan

    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();
    }

Referensi: https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx#M:System.Data.Entity.Infrastructure.DbEntityEntry .Reload

RX_DID_RX
sumber
3
Saya tidak bisa membuatnya berfungsi untuk memuat ulang properti navigasi anak.
Paul
@David dapat Anda gunakan context.ReloadNavigationProperty(parent, p => p.Children);jika Anda memilikiclass Parent { ICollection<Child> Children; }
Jinjinov
Di EF Core Anda dapat menggunakan Query (). Load () jadi misalnyacontext.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
Rubenisme
Saya tidak mengerti mengapa solusi ini sangat disukai. context.Entry (entitas) .Collection <TElement> (navigationProperty) .Query () tidak memuat ulang koleksi anak. Ini hanya memberi Anda Iquerizable yang mewakili kueri yang digunakan untuk mendapatkan koleksi. Ini benar-benar tidak melakukan apa-apa.
statler
72
yourContext.Entry(yourEntity).Reload();
kravits88
sumber
3
Terima kasih untuk solusi mudahnya. Saya tidak melihat perlunya merangkum ini dalam metode ekstensi seperti yang dilakukan RX_DID_RX
Thomas
Ini adalah penyelamat bagi saya. Terima kasih!
Kevin
19
Perhatikan bahwa ini tidak memuat ulang properti navigasi koleksi, hanya entri entitas itu sendiri.
James Wilkins
28

Jika Anda ingin memuat ulang entitas tertentu, dengan DbContextApi, RX_DID_RX sudah memberi Anda jawabannya.

Jika Anda ingin memuat ulang / menyegarkan semua entitas yang Anda muat:

Jika Anda menggunakan Entity Framework 4.1+ (EF5, atau EF 6 mungkin), DbContext API:

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

Jika Anda menggunakan entityFramework 4 (ObjectContext API):

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);
}

Nasihat terbaiknya adalah, coba gunakan "konteks berumur pendek" dan Anda akan terhindar dari masalah semacam ini.

Saya menulis beberapa artikel tentang masalah ini:

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

Christian Rodriguez
sumber
bagus !! Menyelamatkan hariku!
Radu D
15

Gunakan metode Refresh :

context.Refresh(RefreshMode.StoreWins, yourEntity);

atau sebagai alternatif, buang konteks Anda saat ini dan buat yang baru.

Alberto
sumber
@JMK Apa sebenarnya yang tidak bekerja di sini? Tampaknya berfungsi dengan baik untuk saya (EF 6.1.1).
Sebastian Krysmanski
@SebastianKrysmanski Saya berkomentar hampir setahun yang lalu, mungkin sudah diperbaiki sejak itu?
JMK
5
Saya pikir ini hanya bekerja untuk objectcontext tetapi tidak dbcontext. Diperlukan percakapan di antara mereka
batmaci
3
@batmaci Yang dapat dengan mudah dilakukan dengan((IObjectContextAdapter)dbContext).ObjectContext
Daniel Z.
3
Yang tidak disebutkan sedikit tidak lengkap.
pengguna441521
6

konteks.Reload () tidak bekerja untuk saya di MVC 4, EF 5 jadi saya melakukan ini.

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

dan bekerja dengan baik.

Chaudhary Kaleem Ahmad
sumber
1

EF 6

Dalam skenario saya, Entity Framework tidak mengambil data yang baru diperbarui. Alasannya mungkin data diperbarui di luar cakupannya. Menyegarkan data setelah mengambil menyelesaikan masalah saya.

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);
}
Mahbubur Rahman
sumber
1
Saya dengan EF6. Mengapa ini lebih baik daripada a _context.Entry(entity).Reload();?
Csaba Toth
Sejauh yang saya ingat, .Reload()tidak tersedia di EF6. @CsabaToth
Mahbubur Rahman
0

Menyegarkan konteks db dengan Reload bukanlah cara yang disarankan karena kinerja menurun. Ini sudah cukup baik dan merupakan praktik terbaik untuk menginisialisasi instance baru dari dbcontext sebelum setiap operasi dijalankan. Ini juga memberi Anda konteks terkini yang disegarkan untuk setiap operasi.

using (YourContext ctx = new YourContext())
{
   //Your operations
}
aog
sumber
6
Kawan .. Membuang konteks Anda setiap saat juga akan menyegarkan hal-hal yang tidak ingin Anda perbarui, yang benar-benar akan menyebabkan Masalah Kinerja.
LuckyLikey
2
Ini adalah ide yang buruk karena mempengaruhi kemampuan menulis tes unit. Jika kode Anda mati dan memberitakan konteks baru, bagaimana itu akan bekerja selama unit test?
pemenang
5
Akan berguna bagi saya dan orang lain jika Anda menunjukkan beberapa contoh daripada membuat kritik.
aog
Ini bagus untuk situs web kecil.
alikuli
-7

Aku telah membuat kepalaku sendiri sakit hati karena tidak ada apa-apa! Jawabannya sangat sederhana- Saya baru saja kembali ke dasar ...

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

tambahkan baris ini di bawah ini setelah Anda memperbarui / menghapus - Anda memuat ulang metode sistem tanpa entitas Anda.

e2 = new some_Entities(); //reset.
buffy555
sumber
2
Itu akan "berhasil" - itu hanya ide yang buruk dan akan memiliki konsekuensi lain
Adam Hey