2

ルールのテーブルに一連のルールを「一括」挿入しようとしています。テーブルの構造は次のとおりです。

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テーブルに対応するDataTableです(つまり、同じスキーマを持っています)。

質問:レコードのリストを指定して、行に列の値を設定する適切な方法は何ですか?

4

3 に答える 3

3

GetSchemaTableあなたがそれをすることを期待しているように見えることをしません。DataTable行はソーステーブルの列であり、列はそれらの列に関するメタデータである aを返します。

指定されたテーブルのスキーマで「空」を取得する場合は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です)。

于 2012-10-10T22:08:09.727 に答える
2

たぶん、次のようなものを使用してテーブルを生成できます。

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;
}
于 2012-10-10T22:09:15.430 に答える
0

GetSchemaTableは、DataReader selectによって返される構造と同じ構造のDataTableを返しません。同じスキーマ(ColumnName、ColumnSizeなど)を持つテーブルを返し、スキーマはDataTable行にあります。

あなたの場合、この選択でDataTableを取得する必要があります。そうすると、空のRulesTableが取得されます。そうすれば、返されたDataTable(この場合はrulesTable)に新しい行を挿入し、データベースに更新を戻すことができます。

于 2012-10-10T22:06:39.653 に答える