[英]Set a specific column in a DataRow
我正在嘗試執行“批量”將一組規則插入規則表中。 該表具有以下結構:
RuleId int,
Rule nvarchar(256),
Domain nvarchar(256),
RuleTypeId int,
ExpirationDate DateTime
在插入函數中,我嘗試在獲取表的架構后設置行的列,但是似乎該行不包含指定的列( 請注意,由於它是自動的,因此我不指定RuleId生成 ):
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());
}
}
}
這是獲取指定表的架構的函數:
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;
}
問題: 當我嘗試設置特定的列時,它告訴我該列不存在。
異常消息:
An unhandled exception of type 'System.ArgumentException' occurred in System.Data.dll
Additional information: Column 'Rule' does not belong to table SchemaTable.
我懷疑獲取表架構實際上沒有給我Rule
Table,而是SchemaTable
。 我真正想要得到的是與Rule
表相對應的DataTable(即,它具有相同的架構)。
問題: 給定記錄列表,在行中設置列值的正確方法是什么?
GetSchemaTable
並沒有執行您期望的樣子。 它返回一個DataTable
,其中行是源表的列,而列是關於這些列的元數據。
如果要使用給定表的架構獲取“空” DataTable
,請將函數更改為:
private DataTable GetSchemeForTable(string tableName)
{
DataTable ret = new DataTable();
try
{
connection.Open();
SqlCommand command = connection.CreateCommand();
command.CommandText = string.Format("SELECT * FROM [{0}] WHERE 1 = 2;", tableName);
using (IDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly))
{
ret.Load(reader);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception in GetSchemeForTable: " + ex.ToString());
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
connection.Dispose();
}
return ret;
}
請注意,由於您無論如何都要在finally塊中處置連接,因此我取出了using
塊(這實際上是using
所做的事情)。
也許您可以使用類似以下的方法來生成表:
GenerateDataTable(typeof(Rule));
private DataTable GenerateRulesDataTable(Type type)
{
DataTable table = new DataTable();
// build table columns
foreach (PropertyInfo propInfo in type.GetProperties())
{
Type colType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType;
DataColumn col = new DataColumn(propInfo.Name, colType);
table.Columns.Add(col);
}
return table;
}
GetSchemaTable不會返回具有與DataReader select返回的結構相同的結構的DataTable,它會還原具有相同架構(ColumnName,ColumnSize等)的表,並且您的架構位於DataTable行中。
在您的情況下,您應該使用此選擇獲取DataTable,然后您將獲得空的RulesTable。 這樣,您將能夠將新行插入返回的DataTable(在您的情況下為rulesTable)並執行更新回數據庫的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.