该进程无法访问该文件,因为它正被另一个进程使用 --- EF Core 序列化 XML

The process cannot access the file because it is being used by another process --- EF Core serializing XML

我正在尝试编写一种方法来从 Northwind 数据库中获取类别及其各自的产品,然后使用 xml 序列化写入文件。

我尝试了以下代码,但得到了标题中详细说明的错误。 (文件已创建但未写入 XML)。

有谁能告诉我我的代码有什么问题吗?任何帮助将不胜感激。谢谢。

static async void SerializeCategoriesWithXML() {
    FileStream xmlFileStream = null;
    XmlWriter xml = null;

    // Create file to write to :
    string path = Combine(CurrentDirectory, "CategoriesAndTheirProducts.xml");
    // Create a file stream :
    xmlFileStream = File.Create(path);

    // Wrap the file stream in an Xml writer helper and automatically indent the nested elements :
    xml = XmlWriter.Create(xmlFileStream, new XmlWriterSettings { Indent = true });

    using (var db = new NorthwindContext())
    {

        // A query to get all categories and their related products :   
        IQueryable<Categories> cats = db.Categories
            .Include(c => c.Products
            .ToList());

        await using (FileStream stream = File.Create(path))
        {
            // Write the Xml declaration :
            xml.WriteStartDocument();

            // Serialize the object graph to the stream :
            foreach (Categories c in cats)
            {
                // Write a root element :
                xml.WriteStartElement("category");
                foreach(Products p in c.Products)
                {
                    xml.WriteElementString("product", p.ProductName);
                }
                // Write the closing root element :
                xml.WriteEndElement();
                xml.Flush();                        
            }

            // CLose the helper and stream :
            xml.Close();
            xmlFileStream.Close();
        }
    }
}

共享的代码存在多个问题。

让我们尝试理解每个问题并想出可能的解决方案 -
据我了解,问题陈述是,您想创建一个 XML 文件,其中包含类别和类别下的产品。因此,为简单起见,我假设您正在尝试获取如下所示的 XML 文件 -

<?xml version="1.0" encoding="utf-8"?>
<categories>
  <category>
    <product>Chai</product>
    <product>Chang</product>
    <product>Guaraná Fantástica</product>
    <product>Sasquatch Ale</product>
    <product>Steeleye Stout</product>
    <product>Côte de Blaye</product>
  </category>
  <category>
    <product>Aniseed Syrup</product>
    <product>Chef Anton's Cajun Seasoning</product>
    <product>Chef Anton's Gumbo Mix</product>
    <product>Grandma's Boysenberry Spread</product>
  </category>
</categories>

上面发布的代码有什么问题 -
问题 1:多次创建具有指定路径的文件 -

// Create a file stream :
xmlFileStream = File.Create(path);

你已经在上面的行中触发了 File.Create 所以当你触发下面的代码时它说 file already in use...(下面行不是必需的)

await using (FileStream stream = File.Create(path))

问题二:Linq查询不对。您可以使用以下代码替换您的 linq 查询 -

var cats = db.Categories
      .Include(c => c.Products).ToList();

问题三:Xml构造错误...
您需要将类别标签包装在父级中,因为将创建多个类别对象。同样在上面的代码中,您试图在读取一个类别时刷新 xml 。您需要在最后一次执行 flush

xml.WriteEndElement();

被执行。

因此您可以将创建 xml 的代码块替换为如下 -

            // Write the Xml declaration :
            xml.WriteStartDocument();
            xml.WriteStartElement("categories");

            // Serialize the object graph to the stream :
            foreach (Categories c in cats)
            {
                // Write a root element :
                xml.WriteStartElement("category");
                foreach (Products p in c.Products)
                {
                    xml.WriteElementString("product", p.ProductName);
                }

                // Write the closing root element :
                xml.WriteEndElement();                    
            }

            xml.WriteEndElement();
            xml.Flush();

            // CLose the helper and stream :
            xml.Close();
            xmlFileStream.Close();

现在应该使用 categories->category[].
创建文件 以及每个类别->产品[].

谢谢