2

次の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>

このxmlを介してデータベースに挿入しようとして3時間失敗しました。以下のコードを使用して、コードでコメントされた結果を取得しました。

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コマンドを作成するにはどうすればよいですか?

前もって感謝します。

4

2 に答える 2

3

あなたはノードでaを実行しようとしてSelectManyrecordます(意味的には、それぞれ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') 
于 2012-06-06T06:27:33.357 に答える
0

扱っている問題は、テーブルごとunion allに複数のレコードがあり、1つのステートメントに複数のレコードを挿入するために使用する必要があることです。以下のコードは少し不器用ですが、あなたが望むことをします。

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' 
于 2012-06-06T06:36:34.553 に答える