1

Я создаю приложение связи (с использованием .NET 1.1 сердечника и MVC signalr/нокаута) и у меня есть следующий Pocos:EntityFramework кэширование старых устаревших данных, и я не знаю, как остановить это

номер пользователя поста postRevision

сообщений является контейнером postRevision, который для удобства имеет ссылку на последнюю версию

все остальное, как вы себе это. Очевидно, я опускаю много деталей.

У меня есть свойство с аватаром. Когда я обновляю аватар пользователя, я удаляю свой старый аватар и обновляюсь до нового. Затем в комнате посты (по-русски), у упомянутого пользователя больше нет дружеского аватара, теперь у них сломанный значок изображения. Я все еще разрабатываю, так что это не происходит в многопользовательском сценарии. Это только я, прыгающий с контроллера mvc, который меняет аватары на страницу signalr/knockout, на которой отображаются сообщения.

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

в моем контроллере у меня есть этот код:

user.Avatar = imageId.ToString(); 
_context.Entry(user).State = EntityState.Modified; 
await _context.SaveChangesAsync(); 

_context.Entry(user).State = EntityState.Detached; 
return new JsonResult(new { status = "sucess" }); 

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

data = await _context.Posts 
    .Include(x=> x.LatestRevision) 
    .Include(x => x.LatestRevision.Blob) 
    .Include(x => x.LatestRevision.Creator) 
    .Where(x=> x.Room.Id == roomId 
     && x.Id < currentPostId) 
    .OrderByDescending(x => x.Id) 
    .Take(_roomPageSize).ToListAsync(); 

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

services.AddDbContext<ApplicationDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

services.AddIdentity<ApplicationUser, IdentityRole>() 
    .AddEntityFrameworkStores<ApplicationDbContext>(); 
+0

У вас тот же экземпляр DbContext? Если вы это сделаете, это, скорее всего, проблема. – Pawel

+0

Где и когда вы создаете и размещаете '_context'? –

+0

@GertArnold Я использую стандартный инжектор зависимости IoC с контекстом как параметр конструктора на контроллере. Это то, на что намекает файл startup.cs. Полагаю, у вас не было большого опыта работы с ядром .net. – Josiah

ответ

1

Я до раздавливания, добавив

ServiceLifetime.Transient 

к моему AddDbContext вызова, что делает контекст DB имеют переходную продолжительность жизни. Поэтому каждый запрос создает новый контекст.

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient); 
1

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

Я знал точный объект пользователя, который в настоящее время отображается со старыми данными, и я назвал

_context.Entry(user).State = EntityState.Detached; 

перед запуском моего запроса в ступице. Это ничего не делало. Старые данные все еще отображались. (В режиме реального использования это не было бы так просто, но я единственный пользователь в системе прямо сейчас)

Что в конечном итоге работает добавлял эту строку на мой запрос в ступице:

.AsNoTracking() 

это означает, что я теряю все кеширование, и поскольку 99% изменений будут корректно протекать через контекст концентратора, который кажется позором, но он работает сейчас.

Интересно Если я не буду изменять, как я сохраняю объекты на стороне MVC, чтобы мои действия использовали контекст концентратора, таким образом, он всегда находится в цикле. Мне нужно было бы добавить .AsNoTracking() в нескольких местах на стороне MVC, но это лучшее место для его размещения.

Вот сообщение о том, как сделать это: SignalR + posting a message to a Hub via an action method

-Edit: выше ссылка только для вызова методов клиента. До сих пор нет хорошего способа вызвать код концентратора на стороне сервера. См Use Hub methods from controller?

 Смежные вопросы

  • Нет связанных вопросов^_^