Можно ли запросить Entity Framework перед вызовом DbContext.SaveChanges?
В этом простом примере у меня есть два объекта: Event и Address. Я использую консольное приложение каждую ночь для импорта данных из источника 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() после каждого события, поэтому я хотел бы сделать все это в конце (или делать это партиями, но это не относится к этой проблеме). Однако, когда я запрашиваю контекст .Addresses, он, похоже, не знает о каких-либо новых адресах, пока я не вызову context.SaveChanges(), поэтому я получаю дубликаты записей.
Для моих целей может быть хорошо сохранить после каждой записи, а не в конце, но я хотел бы знать, есть ли хорошая простая альтернатива.
Ответы
Ответ 1
При запросе таким образом, чтобы база данных была затронута, новые добавленные объекты в контексте не включаются в результат.
В EF 4.1 вы можете получить их через DbSet<T>.Local
Смотрите:
Почему запросы Entity Framework не возвращают несохраненные объекты
и
Entity Framework: переименование объектов, недавно добавленных в контекст
Ответ 2
Запрос непосредственно к DbSet всегда будет отправлять запрос в базу данных. В объекте Entity Framework 5 - DbSet.Local есть хорошая альтернатива, позволяющая работать с данными в памяти (созданной вами или загруженной из базы данных).
Посмотрите эту статью: http://msdn.microsoft.com/en-us/data/jj592872.aspx.