I’m trying to perform a “bulk” insert a set of rules into a table of rules. The table has the following structure:
RuleId int,
Rule nvarchar(256),
Domain nvarchar(256),
RuleTypeId int,
ExpirationDate DateTime
In my insertion function I try to set the columns of a row after I’ve obtained the schema of the table, but it appears that the row does not contain the specified column (note that I don’t specify the RuleId since it’s auto-generated):
private void InsertRulesXml(List<Rule> rules)
{
using (DataSet ds = new DataSet())
{
using (DataTable rulesTable = GetSchemeForTable("RulesTable"))
{
// Add the rules to the table
foreach (Rule rule in rules)
{
DataRow row = rulesTable.NewRow();
// When I try to set the specific column it tells me that the column doesn't exist
row["Rule"] = rule.Rule;
row["Domain"] = rule.Domain;
row["RuleTypeId"] = rule.RuleTypeId;
row["ExpirationDate"] = rule.Expiration;
rulesTable.Rows.Add(row);
}
ds.Tables.Add(rulesTable);
// Convert the data to XML
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
rulesTable.WriteXml(sw, System.Data.XmlWriteMode.WriteSchema);
}
// Insert the XML rules
InsertUpdateRulesXml(sb.ToString());
}
}
}
Here is the function that gets the schema for the specified table:
private DataTable GetSchemeForTable(string tableName)
{
DataTable ret = null;
using (SqlConnection connection = GetContentScraperSqlConnection())
{
try
{
connection.Open();
SqlCommand command = connection.CreateCommand();
command.CommandText = string.Format("SELECT TOP 0 [{0}].* FROM [{0}] WHERE 1 = 2;", tableName);
using (IDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly))
{
ret = reader.GetSchemaTable();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception in GetSchemeForTable: " + ex.ToString());
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
connection.Dispose();
}
}
return ret;
}
Problem: When I try to set the specific column it tells me that the column doesn’t exist.
Exception Message:
An unhandled exception of type 'System.ArgumentException' occurred in System.Data.dll
Additional information: Column 'Rule' does not belong to table SchemaTable.
I suspect that the getting the table schema does not actually give me Rule table, but the SchemaTable. What I really want to get is the DataTable which corresponds to the Rule table (i.e. it has the same schema).
Question: What’s the proper way to set the column values in a row given a list of records?
GetSchemaTabledoes not do what it looks like you’re expecting it to do. It returns aDataTablewhere the rows are the columns of the source table and the columns are metadata about those columns.If you want to get an “empty”
DataTablewith the schema of the given table, change your function to:notice I took out the
usingblock since you’re disposing of the connection in your finally block anyways (which is essentially whatusingdoes).