2015-08-05 2 views
2

Мы используем Generic шаблон Repo, который я вижу некоторые голоса называет его антипаттерн, но лучше, чтобы начать что-то потом сидеть и ждать, пока все, чтобы закончить :-)SaveChanges Vs Асинхронный в EntityFramework

Senario 1

var placeStatus = await _placeService.AddAsync(oPlace, false); // here false just add to context and don't hit Savechanges 
var orgStatus = await _organizationService.AddAsync(oOrganization, false); 
_unitOfWork.SaveChanges(); 

Vs

Task<short> placeStatus = _placeService.AddAsync(oPlace, true); 
Task<short> orgStatus = _organizationService.AddAsync(oOrganization, true); 
await Task.WhenAll(placeTask, orgTask); 

С моим ограниченным знанием я предполагаю, что SaveChanges() сохраняет откатить внутренний в первом случае, тогда как мне придется обрабатывать откат во втором случае. Я также предполагаю, что параллельное выполнение от await Task.WhenAll

1) так что SaveChanges() параллельно? или перформанс, чем второй, если атомарность не проблема или проблема, и я на правильном пути, если я делаю второй?

Senario 2

Task<Place> placeTask= _placeCore.SelectByIdAsync(id); 
Task<Organization> organizationTask = _organizationCore.SelectByIdAsync(id); 
await Task.WhenAll(placeTask, organizationTask); 

2) Могу ли я пропустить объединения (который может нарушить всю концепцию общего репо) в родовой шаблон репо с использованием Await, как на Senario 2.

Любые ссылки, книги ссылка или история была бы полезна

Благодаря

+0

ли версия с WhenAll работы на практике? Я думаю, что вы не можете запускать два запроса параллельно в одном EF DataContext, но я могу ошибаться. – Stilgar

+0

@Stilgar Это не помогло, только когда я отлаживал медленное разрешение datacontext для запуска в последовательном порядке :-) – brykneval

+0

Ну, тогда вы просто не можете этого сделать (по крайней мере, не с одним EF DataContext) – Stilgar

ответ

0

Вот некоторые несколько вставок с помощью EF 6

foreach (var item in arryTags) 
{ 
    // Some Logic 
    _contentTagMapperRepository.Insert(oContentTagMapper); 
} 
_unitOfWork.SaveChanges(); 

используя единицу работы следа на профилировщике

enter image description here

Так что, кажется, в целом EF делают параллельные вставки на миллисекунды интервала времени так на senario 1, я думаю, что unitofWork идеально подходит.

На Senario 2 наиболее вероятно присоединяется сделает задачу

0

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

Правильный способ использования EF - использовать не-async, non-SaveChanges, вызывающие методы «Добавить/обновить/удалить» и методы async Select. Ваш SaveChanges должен быть асинхронным и вызвать в SaveChangesAsync DataContext. SaveChanges будет загружать ваши вставки, обновления и удалять вместе.

+0

делает пакетную вставку из savechanges более или менее эквивалентно ожиданию Task.WhenAll (placeTask, orgTask); в плане параллельного выполнения? – brykneval

+0

Для вставок/обновлений/удалений я не ожидаю, что это будет.Я считаю, что параллельное выполнение (которое снова не работает в одном контексте данных с EF6) откроет два отдельных соединения с базой данных, в то время как один SaveChanges будет использовать одно соединение и пакетные фактические запросы. Выборы будут отличаться, так как выбор выполняется немедленно (за исключением ленивого выполнения LINQ). ЕСЛИ параллельная версия фактически работает с одним контекстом данных. – Stilgar

+0

поэтому EF делает параллель, я думаю, и я ответил – brykneval

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