6

リフレクションを使用して、いくつかの厳密に型指定されたデータテーブルを .NET アプリケーションにロードする方法を以下に記述しました。以下のように実行すると、スローされた例外を含め、すべてが機能します。しかし、代わりにコメント部分を使用すると (他のすべてを同じに保持)、Failed to enable Constraintsエラーが表示されます here: enter link description here

エラー配列の内容を見ると、常に次のようになります。

"Column 'AEDelegateName' does not allow DBNull.Value."

エラーの ItemArray は次のようになります。

[0] = {}
[1] = "Some Value"

上記のように 2 列ではなく、1 列を選択するスクリプトでは 1 列しか期待できないので、これには驚かされます。また、そのうちの1つがnullのように見えるため、これは問題に近いと思います。

私のスクリプトは null を返さず、使用するクエリでNOT NULLのようなことを言うだけでなく、すばやく視覚的に確認することもできます。

private void GetData(string query, Component tableAdapter)
{
    OracleCommand command = new OracleCommand();
    command.Connection = conn;
    command.CommandText = query;
    command.CommandType = CommandType.Text;
    command.CommandTimeout = 3000;
    OracleDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult);
    MethodInfo[] methods = tableAdapter.GetType().GetMethods();
    MethodInfo getDataMethod = tableAdapter.GetType().GetMethod("GetData");
    DataTable table = (DataTable)getDataMethod.Invoke(tableAdapter, null);
    Type[] paramTypes = new Type[] { table.GetType() };
    MethodInfo updateMethod = tableAdapter.GetType().GetMethod("Update", paramTypes);
    foreach (DataRow row in table.Rows)
    {
        row.Delete();
    }
    //try
    //{
    //    if (reader.HasRows)
    //    {
    //        table.Load(reader, LoadOption.OverwriteChanges, FillErrorHandler);
    //    }
    //}
    //catch (Exception e)
    //{
    //    DataRow[] errors = table.GetErrors();
    //}
    while (reader.Read())
    {
        try
        {
            List<object> newRow = new List<object>();
            for (int i = 0; i < reader.FieldCount; ++i)
            {
                object currentValue = reader.GetValue(i);
                Debug.WriteLine("Value: "+currentValue);
                newRow.Add(currentValue);
            }
            table.Rows.Add(newRow.ToArray());
        }
        catch (ConstraintException e)
        {
            DataRow[] errors = table.GetErrors();
        }
    }            
    updateMethod.Invoke(tableAdapter, new object[]{table});
    reader.Close();
}
4

1 に答える 1

1

DataTable.Load Method (IDataReader, LoadOption)のドキュメントによると、以下の抜粋で説明されている動作に遭遇する可能性があると思われます。クエリから返された列数と DataTable の列数を確認しましたか? クエリから返された列の名前は、DataTable 内の目的の列名と一致していますか?

条件:スキーマには互換性がありますが、読み込まれた結果セットのスキーマに含まれる列が DataTable よりも少ない。

動作: 欠落している列に既定値が定義されているか、列のデータ型が NULL 可能である場合、Load メソッドを使用して、欠落している列を既定値または NULL 値に置き換えて行を追加できます。デフォルト値または null を使用できない場合、Load メソッドは例外をスローします。特定の既定値が指定されていない場合、Load メソッドは暗黙の既定値として null 値を使用します。

while ループ内のコードは、スキーマの一致を試みないため、おそらく機能しています。値を位置的に埋めるだけで、型に互換性があり、制約に違反しておらず、配列に行の列よりも多くの項目が含まれていない限り、成功します。

于 2013-03-13T23:03:03.353 に答える