Можно ли запросить Entity Framework перед вызовом DbContext.SaveChanges?
В этом простом примере у меня есть две сущности: событие и адрес. У меня есть консольное приложение, работающее каждую ночь, чтобы импортировать данные о событиях из источника XML и добавить их в мою базу данных.
Когда я зацикливаюсь на узлах событий XML (внутри контекста Entity Framework), я проверяю, есть ли запись адреса с заданными значениями уже в базе данных. Если нет, то добавляется новая запись.
using (DemoContext context = new DemoContext())
{
foreach (XmlNode eventNode in eventsXml.SelectNodes("/Events/Event"))
{
Event newEvent = new Event();
newEvent.Title = **get from XML**
Address address = context.Addresses.Where(a =>
a.Title.Equals(title, StringComparison.OrdinalIgnoreCase) &&
a.Address1.Equals(address1, StringComparison.OrdinalIgnoreCase) &&
a.Address2.Equals(address2, StringComparison.OrdinalIgnoreCase) &&
a.City.Equals(city, StringComparison.OrdinalIgnoreCase) &&
a.State.Equals(state, StringComparison.OrdinalIgnoreCase) &&
a.ZipCode.Equals(zipCode, StringComparison.OrdinalIgnoreCase)
).FirstOrDefault();
if (address != null)
newEvent.Location = address;
else
{
newEvent.Location.Title = title;
newEvent.Location.Address1 = address1;
newEvent.Location.Address2 = address2;
newEvent.Location.City = city;
newEvent.Location.State = state;
newEvent.Location.ZipCode = zipCode;
}
context.Events.Add(newEvent);
}
context.SaveChanges();
}
Я знаю, что вызывать context.SaveChanges() после каждого события медленнее, поэтому я хотел бы сделать все это в конце (или делать это партиями, но это не относится к данной проблеме). Однако, когда я выполняю запрос к context.Addresses, кажется, что он не знает о каких-либо новых адресах до тех пор, пока я не вызову context.SaveChanges(), поэтому я получаю дубликаты записей.
Для моих целей было бы неплохо сохранять после каждой записи, а не в конце, но я хотел бы знать, есть ли хорошая, простая альтернатива.
2 ответа
Когда вы запрашиваете способ касания базы данных, то вновь добавленные сущности в контексте не включаются в результат. В EF 4.1 вы можете получить их через DbSet<T>.Local
Увидеть:
Почему запросы Entity Framework не возвращают несохраненные объекты
А также
Entity Framework: повторный поиск объектов, недавно добавленных в контекст
Запрос непосредственно к DbSet всегда будет отправлять запрос в базу данных. В Entity Framework 5 есть хорошая альтернатива - свойство DbSet.Local, которое позволяет работать с данными в памяти (созданными вами или загруженными из базы данных).
Посмотрите эту статью: http://msdn.microsoft.com/en-us/data/jj592872.aspx.