Entity framework 4 反序列化实体框架对象在数据库中创建重复记录

Entity framework 4 反序列化实体框架对象在数据库中创建重复记录,entity-framework-4,xmlserializer,self-tracking-entities,Entity Framework 4,Xmlserializer,Self Tracking Entities,我从数据库中获得了一些.NET4实体框架对象,然后将它们序列化为XML。然后我退出WPF应用程序(清除内存)。然后我重新启动WPF应用程序,将它们读回(反序列化)列表,但从不将它们附加到任何EF上下文。当我在对象上下文上调用SaveChanges()时,它会创建重复的记录,但我从未将反序列化的记录附加到上下文,因此我不确定新上下文为什么要创建记录的副本。这与自跟踪实体有关吗 这是一篇评论 启动应用程序 将对象查询到ObjectSet.ToList()中 IQueryable<Rate>

我从数据库中获得了一些.NET4实体框架对象,然后将它们序列化为XML。然后我退出WPF应用程序(清除内存)。然后我重新启动WPF应用程序,将它们读回(反序列化)列表,但从不将它们附加到任何EF上下文。当我在对象上下文上调用SaveChanges()时,它会创建重复的记录,但我从未将反序列化的记录附加到上下文,因此我不确定新上下文为什么要创建记录的副本。这与自跟踪实体有关吗

这是一篇评论

启动应用程序

将对象查询到ObjectSet.ToList()中

IQueryable<Rate> query = DB.EF.Rates.Where({some predicates});

if (query != null && query.Count() > 0)
    _cachedRates = query.ToList();
关闭应用程序

…{later}

再次启动应用程序

从XML文件加载对象时,对象永远不会附加到任何上下文

if (openDialog.ShowDialog().Value)
{
    _cachedRates = null;

    XmlSerializer deserializer = new XmlSerializer(typeof(List<Rate>));
    TextReader textReader = new StreamReader(openDialog.FileName);
    _cachedRates = (List<Rate>)deserializer.Deserialize(textReader);
    textReader.Close();
}
if(openDialog.ShowDialog().Value)
{
_cachedRates=null;
XmlSerializer反序列化器=新的XmlSerializer(typeof(List));
TextReader=newstreamreader(openDialog.FileName);
_cachedRates=(列表)反序列化程序。反序列化(textReader);
textReader.Close();
}
如果用户按下“保存”按钮,它将在上下文中调用.SaveChanges()


问题:我的表中匹配行的数量现在是原来的两倍

因为您正在将对象从一个上下文序列化,然后将它们反序列化回具有不同上下文的对象,您将看到这种行为。从当前上下文中分离对象/项后,如果打开另一个上下文而不将其重新附加到当前上下文,则上下文将认为它是一个新对象。在这种情况下,我们可以选择缓存的速率ID,以便在对上下文调用.SaveChanges()方法之前从上下文中提取这些速率,然后从上下文而不是缓存对象中处理这些速率。我最终需要在我当前的MVC应用程序中执行与此非常类似的操作,因为我要通过JSON发送一个复杂的模型,如果我想正确保存子集合,我需要将父对象复制并附加到具有空子集合的上下文中。然后我直接从上下文查询JSON对象上每个属性中的子对象,并在保存之前将上下文中的子对象分配给附加对象的子对象。这似乎对我有用。如果我试图将反序列化的JSON对象与子对象一起保存,那么最终会在数据库中得到重复的子行

if (openDialog.ShowDialog().Value)
{
    _cachedRates = null;

    XmlSerializer deserializer = new XmlSerializer(typeof(List<Rate>));
    TextReader textReader = new StreamReader(openDialog.FileName);
    _cachedRates = (List<Rate>)deserializer.Deserialize(textReader);
    textReader.Close();
}