c# - Linq 到 xml : generic approach

标签 c# linq linq-to-xml

假设我有以下 xml。

<?xml version="1.0" encoding="utf-8"?>
<importing>
    <table name="Product">
        <records>
            <record>
                <field name="Id" value="1"/>
                <field name="Description" value="iPhone"/>
            </record>
            <record>
                <field name="Id" value="2"/>
                <field name="Description" value="iPad"/>
            </record>
        </records>
    </table>
    <table name="Car">
        <records>
            <record>
                <field name="Id" value="1"/>
                <field name="Name" value="Freelander"/>
                <field name="Brand" value="Land rover"/>
            </record>
            <record>
                <field name="Id" value="2"/>
                <field name="Name" value="Evoque"/>
                <field name="Brand" value="Land Rover"/>
            </record>
        </records>
    </table>
</importing>

我尝试执行 3 个小时,尝试通过此 xml 插入数据库,但未成功。 我通过下面的代码得到了代码中注释的结果。

var filePath = "C:\\xml.xml";
XElement xml = XElement.Load(filePath);

foreach (var t in xml.Descendants("table"))
{
    var tableName = t.Attribute("name").Value;  

    var columns = t.Descendants("field").Select(c=>c.Attribute("name").Value).Distinct();

    var values = t.Descendants("field").Select(c=>c.Attribute("value").Value);

    var command = String.Format("insert into {0} ({1}) values ('{2}')",
                            tableName,
                            String.Join(",",columns),
                            String.Join(",",values));


    Console.WriteLine(command);
    //First pass: insert into Product (Id,Description) values ('1,iPhone,2,iPad')
    //Second pass: insert into Car (Id,Name,Brand) values ('1,Freelander,Land rover,2,Evoque,Land Rover')
}

如果这是一个愚蠢的帖子,我很抱歉,但我无法打破这个...... 如何构建正确的命令?

提前致谢。

最佳答案

您正在寻找SelectMany关于record节点(从语义上讲,您希望在每个 record 中找到每个 table ,无论有多少)。方法如下:

var commands = (from table in xml.Descendants("table")
                from record in table.Descendants("record")
                let tableName = (string)table.Attribute("name")
                let fields = record.Descendants("field")
                let fieldNames = string.Join(", ", fields.Attributes("name").Select(n => n.Value).ToArray())
                let fieldValues = string.Join(", ", fields.Attributes("value").Select(v => string.Format("'{0}'", v.Value.Replace("'", "''"))).ToArray())
                select string.Format("INSERT INTO {0} ({1}) VALUES ({2})", tableName, fieldNames, fieldValues));

commands 中的结果值是:

INSERT INTO Product (Id, Description) VALUES ('1', 'iPhone') 
INSERT INTO Product (Id, Description) VALUES ('2', 'iPad') 
INSERT INTO Car (Id, Name, Brand) VALUES ('1', 'Freelander', 'Land rover') 
INSERT INTO Car (Id, Name, Brand) VALUES ('2', 'Evoque', 'Land Rover') 

关于c# - Linq 到 xml : generic approach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10908520/

相关文章:

c# - 使用 XML to Linq 获取 XML 元素值

c# - 此代码如何处理 INotifyPropertyChanged

C# 获取变量名到字符串

c# - 如何进行嵌套列表操作?

VB.Net XML文档内存管理

c# - 是否可以根据表示其类型的字符串值创建对象实例?

c# - .NET 中的可空类型

c# - 如何从linq中的子表中选择列

c# - 生成数字并在内存中选择

c# - 使用 Entity Framework 和 LINQ 查询大型数据集时如何避免内存溢出