【问题标题】:Insert XML data into SQL database when XML has nodes with same node name当 XML 具有相同节点名称的节点时,将 XML 数据插入 SQL 数据库
【发布时间】:2019-04-26 04:23:43
【问题描述】:

我是 C# 新手,我正在用 C# 开发一个代码,该代码从一个具有 XML 格式数据的变量中读取数据。

一些节点在重复,我的代码只读取重复节点的第一条记录。

我的 XML 示例:

<Stores>
    <Products>
        <Size>Small</Size>
        <ShortName>Coke</ShortName>
        <Id>000001</Id>
        <Description>Drinks</Description>
        <OptionalItemIds>100001</OptionalItemIds>
        <OptionalItemIds>100002</OptionalItemIds>
        <OptionalItemIds>100003</OptionalItemIds>
        <OptionalItemIds>100004</OptionalItemIds>
        <OptionalItemIds>100005</OptionalItemIds>
        <Calories>0</Calories>
        <Name>Diet Coke</Name>
    </Products>
</Stores>

我试过的一段代码:

var ProductList = doc.Root.Elements("Products").Select(element => new JMMEntity
            {
                Size = (element.HasElements == true && element.Element("Size") != null) ? element.Element("Size").Value : String.Empty,
                ShortName = (element.HasElements == true && element.Element("ShortName") != null) ? element.Element("ShortName").Value : String.Empty,
                Id = (element.HasElements == true && element.Element("Id") != null) ? element.Element("Id").Value : String.Empty,
                Description = (element.HasElements == true && element.Element("Description") != null) ? element.Element("Description").Value : String.Empty,
                OptionalItemIds = (element.HasElements == true && element.Element("OptionalItemIds") != null) ? element.Element("OptionalItemIds").Value : String.Empty,
                Calories = (element.HasElements == true && element.Element("Calories") != null) ? element.Element("Calories").Value : String.Empty,
                Name = (element.HasElements == true && element.Element("Name") != null) ? element.Element("Name").Value : String.Empty
            }).ToList();

var xmlNode_Product = new XElement("Stores",
           from Product in ProductList
           select new XElement("Products",
                          new XElement("Size", Product.Size),
                          new XElement("ShortName", Product.ShortName),
                          new XElement("Id", Product.Id),
                          new XElement("Description", Product.Description),
                          new XElement("OptionalItemIds", Product.OptionalItemIds),
                          new XElement("Calories", Product.Calories),
                          new XElement("Name", Product.Name)
                      ));

接下来我调用这个存储过程将数据输入数据库:

INSERT INTO Products(Size, ShortName, Id, Description, OptionalItemIds, Calories, Name)
    SELECT  
        tbl.Stores.value('Size[1]', 'nvarchar(20)') AS Size,
        tbl.Stores.value('ShortName[1]', 'nvarchar(20)') AS ShortName,
        tbl.Stores.value('Id[1]', 'nvarchar(250)') AS Id,
        tbl.Stores.value('Description[1]', 'nvarchar(20)') AS Description,
        tbl.Stores.value('OptionalItemIds.[1]', 'nvarchar(250)') AS OptionalItemIds,      
        tbl.Stores.value('Calories[1]', 'nvarchar(20)') AS Calories,
        tbl.Stores.value('Name[1]', 'nvarchar(20)') AS Name
    FROM 
        @XmlProduct.nodes('/Stores/Products') AS tbl(Stores);

我得到的结果:

    Size    ShortName   ID    Description   OptionalItemIds Calories    Name
    Small   Coke        000001  Drinks          100001           0       Diet Coke

预期结果:

    Size    ShortName   ID    Description   OptionalItemIds Calories    Name
    Small   Coke        000001  Drinks          100001           0       Diet Coke
    Small   Coke        000001  Drinks          100002           0       Diet Coke
    Small   Coke        000001  Drinks          100003           0       Diet Coke
    Small   Coke        000001  Drinks          100004           0       Diet Coke
    Small   Coke        000001  Drinks          100005           0       Diet Coke

【问题讨论】:

  • ID 是数据库中的主键,因此您只能有一行 ID 为 1。您需要更改数据库并从 ID 列中删除主键属性。

标签: c# .net xml visual-studio


【解决方案1】:

您需要使用CROSS APPLY 并分别获取&lt;OptionalItemIds&gt; 的枚举 - 尝试这样的操作:

INSERT INTO Products(Size, ShortName, Id, Description, OptionalItemIds, Calories, Name)
    SELECT  
        tbl.Stores.value('Size[1]', 'nvarchar(20)') AS Size,
        tbl.Stores.value('ShortName[1]', 'nvarchar(20)') AS ShortName,
        tbl.Stores.value('Id[1]', 'nvarchar(250)') AS Id,
        tbl.Stores.value('Description[1]', 'nvarchar(20)') AS Description,
        -- tbl.Stores.value('OptionalItemIds.[1]', 'nvarchar(250)') AS OptionalItemIds,      
        tbl2.ItemIds.value('.', 'int') AS OptionalItemId,
        tbl.Stores.value('Calories[1]', 'nvarchar(20)') AS Calories,
        tbl.Stores.value('Name[1]', 'nvarchar(20)') AS Name
    FROM 
        @XmlProduct.nodes('/Stores/Products') AS tbl(Stores)
    -- get the list of "OptionalItemIds" separately, cross apply to produce rows to be inserted
    CROSS APPLY
        @XmlProduct.nodes('/Stores/Products/OptionalItemIds') AS tbl2(ItemIds)
;

【讨论】:

    【解决方案2】:

    这段代码对我有用,

        INSERT INTO Products(Size, ShortName, Id, Description, OptionalItemIds, Calories, Name)
    SELECT  
        tbl.Stores.value('Size[1]', 'nvarchar(20)') AS Size,
        tbl.Stores.value('ShortName[1]', 'nvarchar(20)') AS ShortName,
        tbl.Stores.value('Id[1]', 'nvarchar(250)') AS Id,
        tbl.Stores.value('Description[1]', 'nvarchar(20)') AS Description,     
        tbl2.ItemIds.value('.', 'nvarchar(20)') AS OptionalItemIds,
        tbl.Stores.value('Calories[1]', 'nvarchar(20)') AS Calories,
        tbl.Stores.value('Name[1]', 'nvarchar(20)') AS Name
    FROM 
        @XmlProduct.nodes('/Stores/Products') AS tbl(Stores)
    CROSS APPLY tbl.Stores.nodes('OptionalItemIds') AS tbl2(ItemIds)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多