DataTable load() 约束错误

6
我写了一个方法,使用反射来在.NET应用程序中加载多个强类型数据表。如果我按照下面的方法运行,一切都正常工作,包括没有抛出任何异常。但是,如果我改为使用注释部分(其余内容相同),那么我会得到“启用约束失败”错误,详细描述请参见这里:进入链接描述
如果我查看错误数组中的内容,总是以下内容:
"Column 'AEDelegateName' does not allow DBNull.Value."

对于错误,ItemArray看起来像这样:

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

这让我感到惊讶,因为我只期望一个选择1列而不是像上面所示的2列的脚本。 我还想象这接近问题,因为其中一个似乎为空。

我的脚本不会返回空值,并且我可以快速,直观地确认它,以及在我使用的查询中说诸如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();
}

你能描述一下 DataTable table 和通过 OracleDataReader 运行的查询之间的关系吗?我感觉两者的模式不同,而 DataTable.Load() 会覆盖定义,从而触发约束。 - Caramiriel
哪个 catch 块正在捕获异常? - radarbob
可能 @Caramiriel 是对的,但我想要做出一个“学过的猜测”,建议在删除行循环之后添加AcceptChanges() - radarbob
2
这意味着使用“非空”或“外键”约束创建的每个表列都必须存在于您的SQL语句或存储过程的结果中。 - radarbob
1个回答

1
根据DataTable.Load Method (IDataReader, LoadOption)的文档,我怀疑您可能遇到了下面摘录的行为。您是否检查了查询返回的列数与DataTable中的列数是否匹配?查询返回的列名是否与DataTable中所需的列名匹配?
引用如下: 条件:模式是兼容的,但加载的结果集模式包含的列比DataTable多。 行为:如果缺少的列定义了默认值或者列的数据类型可为空,则Load方法允许添加行,并将默认值或null值替换为缺少的列。如果不能使用默认值或null,则Load方法会抛出异常。如果没有提供特定的默认值,则Load方法使用null值作为隐含的默认值。
您的while循环代码可能有效,因为它不尝试匹配模式。它只按位置填充值,并在类型兼容、未违反约束且数组不包含比行的列更多的项时成功。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接