在这个简单的例子中,我有两个实体: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()的性能较慢,所以我想在最后完成所有这些(或者分批进行,但这与此问题无关)。但是,当我查询context.Addresses时,它似乎不知道任何新的地址,直到我调用context.SaveChanges(),所以我得到重复的记录。
就我的目的而言,可能可以在每次记录之后而不是在结尾时保存,但我想知道是否有一个好的,简单的替代方案。
答案 0 :(得分:25)
当您以触摸数据库的方式进行查询时,上下文中新添加的实体不会包含在结果中。
在EF 4.1中,您可以通过DbSet<T>.Local
见:
Why do Entity Framework queries not return unsaved entities
和
Entity Framework: Re-finding objects recently added to context
答案 1 :(得分:1)
直接针对DbSet查询将始终向数据库发送查询。 Entity Framework 5中有一个很好的替代方案--DbSet.Local属性,可以让你使用内存数据(由你自己创建或从数据库加载)。