假设我有以下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')
}
如果这是一个愚蠢的帖子我很抱歉,但我无法打破这个...... 如何构建propper命令?
提前致谢。
答案 0 :(得分:3)
您希望在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')
{{1}}中的结果值为:
{{1}}
答案 1 :(得分:0)
您正在处理的问题是每个表有多个记录,您应该使用union all
在一个语句中插入多个记录。下面的代码有点笨拙,但它会做你想要的。
var doc = XElement.Load(@"C:\xml.xml");
var commands = doc.Descendants("table")
.Select(t=>
{
var tableName = t.Attribute("name").Value;
var columns = t.Descendants("field")
.Select(e => e.Attribute("name").Value)
.Distinct()
.ToArray();
var records = t.Descendants("record")
.Select(r => r.Descendants("field")
.Select(e => e.Attribute("value").Value));
var recordValues = records.Select(x => String.Join(", ", x.Select(y=>String.Format("'{0}'", y)).ToArray()));
var selects = recordValues.Select(rv => String.Format("select {0}",rv)).ToArray();
return String.Format("insert into {0} ({1}) {2}", tableName,
String.Join(", ", columns),
String.Join(" union all ", selects.ToArray()));
});
(格式化)输出为:
insert into Product (Id, Description)
select '1', 'iPhone'
union all
select '2', 'iPad'
insert into Car (Id, Name, Brand)
select '1', 'Freelander', 'Land rover'
union all
select '2', 'Evoque', 'Land Rover'