簡體   English   中英

在DataRow中設置特定的列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM