【问题标题】:Bug: List remains in memory if file deleted, and saves data twice if file is deletedBug:如果文件被删除,列表会保留在内存中,如果文件被删除,则会保存两次数据
【发布时间】:2015-07-24 08:52:52
【问题描述】:

我的代码中有一个奇怪的错误,我不明白它为什么会这样。我不是最有经验的代码战士,所以希望有更多经验的人能明白原因。

我正在将对象列表保存到 XML 文件中。我将对象列表传递给我的函数以进行保存,并且我有代码来检查对象是否已经存在,并且仅在对象不存在时才将对象保存到 XML 文件中。如果我按一次“保存”按钮,它会很好地创建文件,并按预期保存。如果我再次按保存,它会再次按预期工作,并且只保存新对象。

我的错误是这样的......

如果我按保存按钮 3 次然后删除文件,当我按保存并重新创建文件时,列表将保存 3 次。就好像以前的列表仍然在浮动,只是相互叠加。

这是我的保存代码... 如果有帮助,我的代码 HasElement() 是 XElement 的扩展方法,并且只返回 FirstOrDefault()。仅当 this 返回为 null 时才会保存。

  public void SaveDB(List<ContactList> cl)
         {
             if (cl != null)
             {
                 if (!File.Exists(DBPath))
                 {
                     XDocument doc = new XDocument(
                         new XDeclaration("1.0", "utf-8", "yes"),
                         new XElement("Contacts")
                         );
                     doc.Save(DBPath);
                     MessageBox.Show("File Created: " + DBPath);
                 }
                 MessageBox.Show(DBPath + " already exists!");
                 XDocument Doc = XDocument.Load(DBPath);
                 List<XElement> elmAdd = new List<XElement>();
                 XElement root = Doc.Element("Contacts");

                 foreach (ContactList CL in cl)
                 { 
                    if (root.HasElement(CL.Name) == null)
                    {
                     if (CL.Selected == true)
                         {
                             XElement eName = new XElement(CL.Name, "true");
                             elmAdd.Add(eName);
                         }
                         else if (CL.Selected == false)
                         {
                             XElement eName = new XElement(CL.Name, "false");
                             elmAdd.Add(eName);
                         }
                     }
                 }


                 MessageBox.Show("Lists saved");
                 Doc.Element("Contacts").Add(elmAdd);
                 Doc.Save(DBPath);
             } // End if null
             else
             {
                 MessageBox.Show("Debug: List is empty");
             }
         } // end method

【问题讨论】:

  • OT:让扩展方法“HasElement()”返回一个布尔值。比:“问:你有元素吗?答:空”。
  • 处理我们正在发生的事情的最简单方法是插入一些断点并逐步完成。没有什么明显的,我的第一个猜测是 cl 包含的项目比你想象的要多。

标签: c# xml linq linq-to-xml xelement


【解决方案1】:

很可能该错误超出了此函数的范围,并且以某种方式传递了具有重复条目的列表。您可以通过使用 Distinct 进行分组或更改您的代码以逐个附加子元素来处理您的函数中的这种情况。但更合适的解决方案是确定如何将重复项添加到源列表中。

【讨论】:

  • 确实如此。我回到我调用保存函数的表单。我出错的地方是我建立了一个用于调试的临时对象列表。这些对象一次又一次地添加到同一个列表中。如果必须重新创建文件,并且多次按下保存,则列表包含相同对象的多个版本。现在感觉很愚蠢......但感谢大家的帮助。
【解决方案2】:

我检查了代码,在我看来,调用部分有问题。现在,当我单击保存时,将contactcontact1contact2 修改为其他值,然后再次单击,旧联系人值与新联系人值一起保存。没关系。当我删除文件并单击保存时,只会写入新值。和的联系中少一个'a'将不会被记住。

private ContactList MyContact { get; set; } // MyContact is initialized with name contact

void Clickery(object o, RoutedEventArgs e)
{
    MyContact = new ContactList
    {
        Name = MyContact.Name + "a",
        Selected = false
    };
}

void Clicky(object o, RoutedEventArgs e)
{
    string DBPath = "somefile.txt";
    List<ContactList> cl = new List<ContactList>() { 
        MyContact,
        new ContactList { Name = "contact1", Selected = false },
        new ContactList { Name = "contact2", Selected = true } };
    if (cl != null)
    {
        if (!File.Exists(DBPath))
        {
            XDocument doc = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XElement("Contacts")
                );
            doc.Save(DBPath);
            MessageBox.Show("File Created: " + DBPath);
        } else {
            MessageBox.Show(DBPath + " already exists!");
        }
        XDocument Doc = XDocument.Load(DBPath);
        List<XElement> elmAdd = new List<XElement>();
        XElement root = Doc.Element("Contacts");

        foreach (ContactList CL in cl)
        {
            if (root.Element(CL.Name) == null)
            {
                if (CL.Selected == true) {
                    XElement eName = new XElement(CL.Name, "true");
                    elmAdd.Add(eName);
                } else {
                    XElement eName = new XElement(CL.Name, "false");
                    elmAdd.Add(eName);
                }
            }
        }

        MessageBox.Show("Lists saved");
        Doc.Element("Contacts").Add(elmAdd);
        Doc.Save(DBPath);
    } else { // End if null
        MessageBox.Show("Debug: List is empty");
    }
} // end method

class ContactList
{
    public string Name { get; set; }
    public bool Selected { get; set; }
}

【讨论】:

    猜你喜欢
    • 2013-03-20
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 2020-04-27
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多