2016-07-27 2 views
1

Если я найду запись в EntityFramework 6 (ADO), а затем попытаться найти эту запись снова, метод Find возвращает 0. Вот пример:EntityFramework 6: Как найти найденную ранее запись?

var db3 = new IMS(); 

db3.TabModuleSettings.Find(973, "ShowSoldOut"); //Local.Count=1 
db3.TabModuleSettings.Local.Clear(); //Local.Count=0 

db3.TabModuleSettings.Find(142, "AllowIndex"); //Local.Count=1 
db3.TabModuleSettings.Local.Clear(); //Local.Count=0 

db3.TabModuleSettings.Find(973, "ShowSoldOut"); //Local.Count=0 
db3.TabModuleSettings.Local.Clear(); //Local.Count=0 

db3.TabModuleSettings.Find(142, "AllowIndex"); //Local.Count=0 

Как найти ранее нашел запись?

ответ

4

Две вещи, чтобы иметь в виду:

  • Если вы Local.Clear() субъекты в Local коллекции помечаются для удаления. Таким образом, объект с ключевыми значениями (973, "ShowSoldOut") все еще присутствует в кэше контекста, но его состояние - Deleted. (То же самое для одного с (142, "AllowIndex"), позже).

  • DbSet.Find сначала ищет сущности в кэш контекста, а затем, когда не найден, он выглядит в базе данных. Если объект найден в кеше, но удален, EF показывает, что его больше не должно быть, и он не возвращает его.

Я не знаю, почему вы делаете эти Local.Clear() звонков, но я надеюсь, вы понимаете теперь, что это заявление использовать с осторожностью.

Правильный способ очистить кэш является отсоединение сущностей, например, для одной Local коллекции:

foreach (var x in db3.TabModuleSettings.Local.ToList()) 
{ 
    Entry(x).State = System.Data.Entity.EntityState.Detached; 
} 

(хотя это не отделится удаленные объекты).

Или весь кэш:

foreach (var entry in db3.ChangeTracker.Entries()) 
{ 
    entry.State = System.Data.Entity.EntityState.Detached; 
} 

(также отделяться удаленные объекты).

Или все объекты определенного типа (включая удаленные):

foreach (var entry in db3.ChangeTracker.Entries<TabModuleSetting>()) 
{ 
    entry.State = System.Data.Entity.EntityState.Detached; 
} 

Хотя обычно вы не должны делать это. Обычно лучше удалять контекст и создавать новый, если вы хотите обновить объекты.

+0

Итак, как мне заставить искать базу данных, а не искать кеш? Или, как я освобождаю кеш? The .Clear предназначен для опорожнения набора результатов. Есть много вещей, которые происходят между операторами .Find. – Chris

+0

Добавлена ​​дополнительная информация. –

+0

ОК. Я думал, что будет удар производительности при утилизации и повторной инициализации класса IMS. В первый раз это занимает около 15 секунд. Но, db3.Dispose() db3 = new IMS(), похоже, не вызывает проблемы с производительностью и обрабатывает то, что мне нужно. – Chris

0

Alrighty. Все, что мне нужно было сделать:

db3.TabModuleSettings = new IMS(). TabModuleSettings;

Все.

+0

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

+0

Ну. на самом деле, нет. Вы указали, что я должен распоряжаться всем контекстом, теряя любые другие сущности, которые могут существовать. Мне все еще нужно сохранить некоторые из моих предыдущих находок. Мой путь, я просто распоряжаюсь выбранным объектом.db3 - мой весь контекст, и я не хочу потерять весь контекст. – Chris

+0

Ах, что вы делаете? Я бы настоятельно советовал этому. Вы заменяете весь DbSet, в то время как трекер изменений контекста по-прежнему содержит информацию об объектах в предыдущем наборе. Это целый ряд странных ошибок, ожидающих своего появления. Если вы удалите выбранные объекты, вы * имеете *, чтобы отсоединить объекты, от которых вы хотите избавиться. Внутри EF будет держать свой трекер изменений (и менеджер отношений) синхронно. Я пересмотрел свой ответ, включив этот сценарий. –