2013-06-18 2 views
1

Я клонирую информацию пользователя, безопасность, отделы и несколько других таблиц информации для создания нового пользователя с одинаковой настройкой. Эта информация отображается через несколько DGV. Когда я использую обычный LINQ в контексте:Более эффективный способ отображения добавлений/удалений в контексте

var x = (from ctx in context.UserInfo 
     where ctx.UserID == userID 
     select ctx); 

отображения информации практически мгновенно, но не отображается добавленный пользователь, если я не называю SaveChanges(), который я стараюсь не делать.

Затем я перешел на использование местной LINQ:

context.UserInfo.Load(); 
var x = (from ctx in context.UserInfo.Local 
     where ctx.UserID == userID 
     select ctx); 

Однако, несколько таблиц я запрашивающие иметь более 30К записей и .local вызов значительно замедляет процесс отображения информации. Из того, что я исследовал, это происходит из-за проверки достоверности.

Затем я попытался с помощью изменения трекера:

context.UserInfo.Load(); 
var x = (from ctx in context.ChangeTracker.Entries<UserInfo>() 
     where ctx.Entity.UserID == userID && ctx.State == EntityState.Unchanged || 
      ctx.State == Entity.State.Added || ctx.State == EntityState.Modified 
     select ctx.Entity) 

Это дало тот же плохую работу в качестве местного вызова.

Есть ли способ быстро отображать добавленные объекты, а не отображать удаленные объекты, без вызова Local или есть способ ускорить локальное?

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

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

Проект делается в C# .net 4.5 и Entity Framework 5.0 на форме Windows

EDIT:

Чтобы дать больше кода о том, как запрос в числе:

У меня есть LoadData(), который инициализирует данные, которые я буду использовать.

public void loadData() 
{ 
    var x = (from ctx in context.UserInfo 
      select ctx).ToList(); 
} 

Я считаю, что это будет делать то же самое, что и выше код

public void loadData() 
{ 
    context.UserInfo.load(); 
} 

Тогда запрос называется: Это быстрый запрос, но не показывает контекст меняется

public List<UserInfo> getUserInfo() 
{ 
    var user = (from ctx in context.UserInfo 
       where ctx.UserID == userID 
       select ctx).ToList(); 

    return user; 
} 

Этот запрос является медленным, но показывает изменения

public List<UserInfo> getUserInfo() 
{ 
    var user = (from ctx in context.UserInfo.Local 
       where ctx.UserID == userID 
       select ctx).ToList(); 

    return user; 
} 
+0

Что происходит до кода, который вы указали? Чтение данных из базы данных? Как добавляются новые сущности? Вы пытались вызвать 'ChangeTracker.DetectChanges()' в соответствующей точке кода? – qujck

+0

Вы думали об использовании EF вместо этого? Он покажет вам добавленного пользователя без необходимости делать SaveCahnges() или загружать все сущности заранее. –

+0

Вся информация находится на datalayer. Загружается репозиторий, устанавливается контекст, а затем выполняется запрос. Все это происходит при загрузке формы. Я добавляю объекты через context.UserInfo.add (пользователь). – EZE

ответ

0

Первоначально я не знал, что ToList() действует так же, как и Load().С этим я изменил свой код, чтобы больше не использовать мой метод loadData(), но инициализирую только те части необходимой мне информации.

public List<UserInfo>(int userID 1) 
{ 
    var data = (from ctx in context.UserInfo 
       where ctx.UserID == userID 
       select ctx).ToList(); 

    List<UserInfo> user = (from ctx in context.UserInfo.Local 
          where ctx.UserID == userID 
          select ctx).ToList(); 

    return user; 
} 

Это изменение позволило моим запросам запустить практически мгновенно и по-прежнему отслеживать адды/удалить/Изменяет в контексте. Единственный недостаток, который я вижу в этом методе, заключается в том, что в объект UserInfo.Local загружается много объектов, он начнет замедляться, хотя в моем случае это, скорее всего, не произойдет.

1

Я собираюсь сделать длинный снимок здесь - я думаю, что задержка не соответствует стандартной задержке, которую EF имеет при инициализации кэша модели. См. my answer on this question для более подробной информации. Вам нужно будет изменить свой код, чтобы точно узнать ...

+0

Это то, что я предположил в своих тестах и ​​исследованиях. Хотя, я думаю, я объяснил это плохо в моем вопросе. «Из того, что я исследовал, это происходит из-за проверки правильности». Предполагалось включить EF, запускать и кэшировать режим, проверяя ассоциации и действительность отношений. Хотя это делается только в звонках .Local, которые я видел. Если я не вызываю .Local, скорость моих запросов почти мгновенная. Это приводит меня к согласию с вашим заявлением, хотя я хочу знать, есть ли в любом случае вокруг этой задержки и по-прежнему показывать изменения в контексте. – EZE

+0

Я бы ожидал, что форма окна, чтобы кэшировать модель, когда-то была скомпилирована. Первым шагом должно быть подтверждение того, что после компиляции остальная часть вашей системы выполняет «правильно». Можете ли вы настроить фиктивные данные, считанные из «UserInfo» при запуске приложения, а затем попробовать свой код? – qujck

+0

Несомненно, могу ли я предположить, что чтение фиктивных данных происходит, загружается и запускается UserInfo.Local при запуске приложения, а затем видно, как реагируют мои DataGridViews, если есть улучшенная производительность? – EZE

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