Как заставить Entity Framework всегда получать обновленные данные из базы данных?


86

Я использую библиотеку EntityFramework.Extended для выполнения пакетных обновлений. Единственная проблема в том, что EF не отслеживает пакетные обновления, выполняемые библиотекой. Поэтому, когда я DbContextснова запрашиваю, он не возвращает обновленные объекты.

Я обнаружил, что использование AsNoTracking()метода при запросе отключает отслеживание и получает свежие данные из базы данных. Однако, поскольку EF не отслеживает запрошенные сущности AsNoTracking(), я не могу выполнить какое-либо обновление запрошенных данных.

Есть ли способ заставить EF получать последние данные при отслеживании изменений?


2
29k просмотров и только 19 голосов за это ... ну, я все равно добавил свой
jleach

Ответы:


148

Попробуйте обновить один объект:

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

Изменить: чтобы получить свежие данные для коллекции сущностей, стоит попытаться удалить DbContextэкземпляр после каждого запроса.


Спасибо! Есть ли способ перезагрузить коллекцию сущностей, а не одну? Желательно весь DbSet.
Saravana

Что еще нужно, чтобы это можно было считать ответом?
PlTaylor 04

1
Да, он все еще не показывает, как перезагрузить коллекцию сущностей.
Saravana

1
Вы пробовали избавиться от своего dbcontext и создать новый?
PlTaylor 05

2
Мне потребовались часы, чтобы прийти к такому выводу. Это РЕДАКТИРОВАНИЕ в ответе помогло мне найти решение. Благодарность!
BeemerGuy 08

17

Я наткнулся на этот вопрос, когда искал решение возникшей у меня проблемы, когда свойства навигации не заполнялись после обновления объекта. Всякий раз, когда я пытался перезагрузить объект из базы данных, вместо этого он брал запись из локального хранилища, что не заполняло свойства навигации посредством отложенной загрузки. Вместо того, чтобы разрушать контекст и воссоздавать его, я обнаружил, что это позволяет мне получать свежие данные с работающими прокси:

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

Логика заключалась в следующем: мое обновление прикрепило объект, чтобы отслеживать изменения в нем. Это добавит его в местный магазин. После этого любые попытки получить объект с помощью функциональных прокси-серверов приведут к захвату локального объекта вместо перехода к базе данных и возврата нового объекта с поддержкой прокси. Я попробовал вариант перезагрузки выше, который обновляет объект из базы данных, но не дает вам проксируемого объекта с ленивой загрузкой. Я пробовал делать Find(id), Where(t => t.Id = id), First(t => t.Id = id). Наконец, я проверил предоставленные доступные состояния и увидел состояние «Отсоединено». Эврика! Надеюсь, это кому-то поможет.


Где вы применяете состояние Detached, чтобы работала отложенная загрузка? Я попробовал ваше решение, и оно не сработало, я что-то упустил. Ваша помощь будет оценена по достоинству
Рекс

2
Я разобрался: 1. сохранить объект, 2. установить состояние на отсоединение, 3. прочитать объект из db. Спасибо за подсказку!
Rex

1

Выполнение кода в одном контексте не приведет к обновлению сущностей. Он будет добавлять только новые сущности, созданные в базе данных между запусками. Перезагрузка EF force может быть выполнена следующим образом:

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

1

Я объявил переменную сущности без присваивания как часть класса. Это позволило мне избавиться от экземпляра без потери переменной для ссылки другими методами. Я только что наткнулся на это, поэтому у него не так много времени выполнения, но пока что, похоже, он работает нормально.

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

Для меня ... я получаю доступ к своему DbContext следующим образом:

_viewModel.Repo.Context

Чтобы заставить EF попасть в базу данных, я делаю следующее:

_viewModel.Repo.Context = new NewDispatchContext();

Перезапись текущего DbContext новым экземпляром. Затем, когда я в следующий раз воспользуюсь услугами службы данных, они получат данные из базы данных.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.