6

我在下面编写了一个方法,使用反射在 .NET 应用程序中加载几个强类型数据表。如果我按以下方式运行,一切正常 - 包括没有抛出异常。但是,如果我改用注释部分(保持其他所有内容相同),那么我会得到Failed to enable constraints错误描述here: enter link description here

如果我查看错误数组中的内容,它总是如下:

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

错误的 ItemArray 将类似于:

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

这让我感到惊讶,因为我只希望脚本中有 1 列选择 1 列,而不是像上面指出的那样选择 2 列。我也认为这与问题很接近,因为其中一个似乎为空。

我的脚本不返回 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。

行为: 如果缺少的列定义了默认值或列的数据类型可以为空,则 Load 方法允许添加行,用默认值或空值替换缺失的列。如果不能使用默认值或 null,则 Load 方法会引发异常。如果没有提供特定的默认值,则 Load 方法使用空值作为隐含的默认值。

您在 while 循环中的代码可能正在工作,因为它没有尝试匹配架构。它只是按位置填充值,只要类型兼容、不违反约束并且数组包含的项目不超过行的列数,它就会成功。

于 2013-03-13T23:03:03.353 回答