在数据行中设置特定列



我正在尝试执行"批量"将一组规则插入规则表中。该表具有以下结构:

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表,而是SchemaTable.我真正想要的是对应于Rule表的数据表(即它具有相同的模式)。

问:在给定记录列表的行中设置列值的正确方法是什么?

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;
}

请注意,我取出了using块,因为无论如何您都在处理 finally 块中的连接(这基本上是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(在您的例子中为 ruleTable)中,并执行"更新回数据库"。

相关内容

  • 没有找到相关文章

最新更新