Khung thực thể Làm mới bối cảnh?


100

Làm cách nào tôi có thể làm mới ngữ cảnh của mình? Tôi có các thực thể dựa trên các chế độ xem từ Cơ sở dữ liệu của mình và khi tôi thực hiện cập nhật trên một bảng Đối tượng có thuộc tính điều hướng đến các chế độ xem, đối tượng được cập nhật nhưng chế độ xem không làm mới theo các bản cập nhật mới ... chỉ muốn lấy lại từ dữ liệu Db. Cảm ơn!

Câu trả lời:


91

Cách tốt nhất để làm mới các thực thể trong ngữ cảnh của bạn là loại bỏ ngữ cảnh của bạn và tạo một ngữ cảnh mới.

Nếu bạn thực sự cần làm mới một số thực thể và bạn đang sử dụng cách tiếp cận Code First với lớp DbContext, bạn có thể sử dụng

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

Để tải lại các thuộc tính điều hướng của bộ sưu tập, bạn có thể sử dụng

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

Tham khảo: https://msdn.microsoft.com/en-us/library/system.data.entity.infraosystem.dbentityentry.reload(v=vs.113).aspx#M:System.Data.Entity.Infra Structure.DbEntityEntry .Reload


3
Tôi không thể làm cho điều này hoạt động để tải lại các thuộc tính điều hướng con.
Paul

@ David bạn có thể sử dụng context.ReloadNavigationProperty(parent, p => p.Children);nếu bạn cóclass Parent { ICollection<Child> Children; }
Jinjinov

Trong EF Core, bạn có thể sử dụng Query (). Load () chẳng hạncontext.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
Rubenisme

Tôi không hiểu tại sao giải pháp này lại được bình chọn cao như vậy. context.Entry (entity) .Collection <TElement> (navigationProperty) .Query () không tải lại tập hợp con. Nó chỉ cung cấp cho bạn một Iqueryable đại diện cho truy vấn được sử dụng để lấy bộ sưu tập. Nó thực sự không làm gì cả.
statler

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

3
Cảm ơn vì giải pháp dễ dàng. Tôi không thấy sự cần thiết trong Encapsulate này trong một phương pháp khuyến nông như RX_DID_RX đã làm
Thomas

Đây là một cứu cánh cho tôi. Cảm ơn bạn!
Kevin

19
Lưu ý rằng điều này không tải lại các thuộc tính điều hướng bộ sưu tập, chỉ tải lại chính mục nhập thực thể.
James Wilkins

28

Nếu bạn muốn tải lại các thực thể cụ thể, với DbContextApi, RX_DID_RX đã cho bạn câu trả lời.

Nếu bạn muốn tải lại / làm mới tất cả các thực thể bạn đã tải:

Nếu bạn đang sử dụng Entity Framework 4.1+ (có thể là EF5 hoặc EF 6), API DbContext:

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

Nếu bạn đang sử dụng entityFramework 4 (API ObjectContext):

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

Lời khuyên tốt nhất là, hãy cố gắng sử dụng một "bối cảnh tồn tại trong thời gian ngắn" và bạn sẽ tránh được loại vấn đề này.

Tôi đã viết một vài bài báo về vấn đề này:

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


một trong những tốt đẹp !! Đã lưu ngày của tôi!
Radu D

15

Sử dụng phương pháp Làm mới :

context.Refresh(RefreshMode.StoreWins, yourEntity);

hoặc thay vào đó, loại bỏ ngữ cảnh hiện tại của bạn và tạo một bối cảnh mới.


@JMK Chính xác thì điều gì không hoạt động ở đây? Nó có vẻ hoạt động tốt đối với tôi (EF 6.1.1).
Sebastian Krysmanski

@SebastianKrysmanski Tôi đã bình luận gần một năm trước, có lẽ nó đã được sửa từ đó?
JMK

5
Tôi nghĩ rằng nó chỉ hoạt động cho objectcontext chứ không phải dbcontext. Một cuộc trò chuyện giữa họ là cần thiết
batmaci

3
@batmaci Điều này có thể dễ dàng thực hiện với((IObjectContextAdapter)dbContext).ObjectContext
Daniel Z.

3
Mà đã không được nêu nên hơi không đầy đủ.
user441521

6

context.Reload () không hoạt động đối với tôi trong MVC 4, EF 5 nên tôi đã làm điều này.

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

và nó hoạt động tốt.


1

EF 6

Trong kịch bản của tôi, Entity Framework không chọn dữ liệu mới được cập nhật. Lý do có thể là dữ liệu đã được cập nhật bên ngoài phạm vi của nó. Làm mới dữ liệu sau khi tìm nạp đã giải quyết được sự cố của tôi.

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
Tôi với EF6. Tại sao điều này tốt hơn a _context.Entry(entity).Reload();?
Csaba Toth

Theo như tôi có thể nhớ, .Reload()không có sẵn trong EF6. @CsabaToth
Mahbubur Rahman

0

Làm mới ngữ cảnh db bằng Tải lại không được khuyến khích do hiệu suất bị mất. Nó đủ tốt và là phương pháp hay nhất để khởi tạo một phiên bản mới của dbcontext trước khi thực thi mỗi thao tác. Nó cũng cung cấp cho bạn bối cảnh cập nhật được làm mới cho mỗi hoạt động.

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

6
Anh bạn .. Đổ ngữ cảnh của bạn mọi lúc cũng sẽ làm mới những thứ bạn không muốn làm mới, điều này thực sự sẽ dẫn đến Vấn đề về hiệu suất.
LuckyLikey

2
Đây là một ý tưởng khủng khiếp vì nó ảnh hưởng đến khả năng viết các bài kiểm tra đơn vị. Nếu mã của bạn tắt và cập nhật một ngữ cảnh mới, thì điều đó sẽ hoạt động như thế nào trong quá trình kiểm tra đơn vị?
victor

5
Sẽ hữu ích cho tôi và những người khác nếu bạn đưa ra một số mẫu hơn là đưa ra những lời chỉ trích.
aog

Nó tốt cho các trang web nhỏ.
alikuli

-7

Tôi đã tự làm cho đầu của mình bị đau vì không có gì! Câu trả lời rất đơn giản- Tôi chỉ quay lại những điều cơ bản ...

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

thêm dòng này bên dưới sau khi bạn cập nhật / xóa - bạn đang tải lại thực thể của mình - không có phương pháp hệ thống ưa thích.

e2 = new some_Entities(); //reset.

2
Điều đó sẽ "hiệu quả" - đó chỉ là một ý tưởng khủng khiếp và sẽ gây ra những hậu quả khác
Adam Này
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.