使用C#将XML导入SQL

我知道这不是运动要求这种帮助,但我已经坚持了一段时间 – 现在我正在阅读两本C#书籍并且每天工作超过9小时。

好的,这是我的问题:我有一个几乎完成的WinForms C#应用程序。 在SQL中我有三个表如下所示:

CREATE TABLE [dbo].[Racuni]( [BROJ] [varchar](12) NULL, [DATUM] [datetime] NULL, [TS] [datetime] NULL, [USER_ID] [int] NULL, [KASA_ID] [varchar](3) NULL, [TOTAL] [float] NULL, [STATUS] [varchar](1) NULL, [ARH] [varchar](max) NULL ) ON [PRIMARY] Create Table "Rac_Npl" ( br_rac Char( 12 ) , kasa_id Char( 3 ) , npl_id Integer , iznos Money); CREATE TABLE [dbo].[Stavke]( [br_rac] [varchar](12) NULL, [kasa_id] [char](3) NULL, [art_id] [int] NULL, [kol] [float] NULL, [mpc] [money] NULL, [ompc] [money] NULL) 

我在本地磁盘上有XML文件用于导入这三个表 – XML如下所示:

   

再一次,我很尴尬以这种方式请求帮助,但我会尝试以任何方式支持StackOverflow。

跨实现不一致地支持多个CDATA元素。 例如,您将无法通过XDocument或SelectNodes访问它们。 如果您可以更改输入格式,这将使事情变得更容易。

此代码尚未经过测试,并且没有error handling或错误的数据检查,但它应该让您入门。 调查使用XPathDocument / XPathNavigator获得性能并阅读我的内联注释。

 class XmlCsvImport { public void ImportData(string xmlData, ConnectionStringSettings connectionSettings) { DbProviderFactory providerFactory = DbProviderFactories.GetFactory(connectionSettings.ProviderName); IDbConnection connection = providerFactory.CreateConnection(); connection.ConnectionString = connectionSettings.ConnectionString; // TODO: Begin transaction XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlData); foreach (XmlNode tableNode in doc.SelectNodes("/transaction/table")) { IDbCommand command = CreatCommand(connection, tableNode); foreach (XmlNode rowNode in tableNode.SelectNodes("data/row")) { string[] values = GetRowValues(rowNode); if (values.Length != command.Parameters.Count) { // TODO: Log bad row continue; } this.FillCommand(command, values); command.ExecuteNonQuery(); } } // TODO: Commit transaction } private IDbCommand CreatCommand(IDbConnection connection, XmlNode tableNode) { string tableName = tableNode.Attributes["name"].Value; IDbCommand command = connection.CreateCommand(); command.Connection = connection; command.CommandType = CommandType.Text; XmlNodeList fieldNodes = tableNode.SelectNodes("fields/field"); List fieldNameList = new List(fieldNodes.Count); foreach (XmlNode fieldNode in tableNode.SelectNodes("fields/field")) { string fieldName = fieldNode.Attributes["name"].Value; int fieldType = Int32.Parse(fieldNode.Attributes["type"].Value); int fieldSize = Int32.Parse(fieldNode.Attributes["size"].Value); IDbDataParameter param = command.CreateParameter(); param.ParameterName = String.Concat("@", fieldNode.Attributes["name"]); param.Size = fieldSize; param.DbType = (DbType)fieldType; // NOTE: this may not be so easy command.Parameters.Add(param); fieldNameList.Add(fieldName); } string[] fieldNames = fieldNameList.ToArray(); StringBuilder commandBuilder = new StringBuilder(); commandBuilder.AppendFormat("INSERT INTO [{0}] (", tableName); string columnNames = String.Join("], [", fieldNames); string paramNames = String.Join(", @", fieldNames); command.CommandText = String.Concat( "INSERT INTO [", tableName, "] ([", columnNames, "]) VALUES (@", paramNames, ")" ); return command; } private string[] GetRowValues(XmlNode row) { List values = new List(); foreach (XmlNode child in row.ChildNodes) { if (child.NodeType == XmlNodeType.Text || child.NodeType == XmlNodeType.CDATA) { values.Add(child.Value); } } return values.ToArray(); } private void FillCommand(IDbCommand command, string[] values) { for (int i = 0; i < values.Length; i++) { IDbDataParameter param = (IDbDataParameter)command.Parameters[i]; param.Value = values[i]; // TODO: Convert to correct data type } } 

您可以使用XPathNavigator对象来解析XML,然后使用SqlCommand对象将数据插入表中。 Internet上的两个对象都有很多代码示例。