来自 SQLDataAdapter.Update 的 FormatException 由空值引起
FormatException from SQLDataAdapter.Update caused by null value
我的 "User" table(SQL 服务器)有一个 (int,null) 列,ActiveWorkRequestId。
我正在尝试使用 SqlDataAdapter 更新 table。这是使用基于 XSD 强类型数据集定义 (Visual Studio 2010) 的默认更新命令的克隆设置的。所以命令看起来像
UPDATE [User] SET [Username] = @p1, [ActiveWorkRequestId] = @p2
WHERE (([Id] = @p3) AND ([Username] = @p4) AND ((@p5 = 1 AND
[ActiveWorkRequestId] IS NULL) OR ([ActiveWorkRequestId] = @p6)))
在此示例中,table "User" 有 3 列:Id、Username 和 ActiveWorkRequestId。参数 p2、p5 和 p6 都有关联的 ActiveWorkRequestId 列。
本例中更新命令(来自修改后的行)的运行时间参数是:
@p1 - "myusername"
@p2 - [DBNull]
@p3 - 126
@p4 - "myusername"
@p5 - [DBNull]
@p6 - [DBNull]
我得到所有更新的行(只有一个返回),然后更新如下。已更改行中的 ActiveWorkRequestId 为空(实际上与原始行中一样)。 "dt" 是我的数据集中填充的数据表。
// This part is inline for convenience, only done once in fact
// Some irrelevant code omitted
string query = String.Format("SELECT * FROM [{0}]", dt.TableName);
string sqlCon = ""; // connection string actually got from settings
SqlDataAdapter da = new SqlDataAdapter(query, sqlCon);
SqlCommandBuilder cb = new SqlCommandBuilder(da);
cb.QuotePrefix = "[";
cb.QuoteSuffix = "]";
da.UpdateCommand = CopyCommandObject(dt, cb.GetUpdateCommand());
// ... This part may execute more than once
DataRow[] foundRows = dt.Select("", "",
DataViewRowState.Added | DataViewRowState.ModifiedCurrent);
da.Update(foundRows); // Exception here
// ... defined elsewhere
private static SqlCommand CopyCommandObject(DataTable dt, SqlCommand cmd)
{
SqlCommand r = new SqlCommand(cmd.CommandText);
r.Connection = cmd.Connection;
foreach (SqlParameter p in cmd.Parameters)
{
DataColumn dc = dt.Columns[p.SourceColumn];
// Put this in since p.IsNullable always seems to be false
bool nullable = dc.AllowDBNull ? true : false;
SqlParameter newParam = new SqlParameter(
p.ParameterName,
p.SqlDbType,
p.Size,
p.Direction,
nullable,
p.Precision,
p.Scale,
p.SourceColumn,
p.SourceVersion,
p.Value);
r.Parameters.Add(newParam);
}
return (r);
}
当我在 SqlDataAdapter 上调用 Update 时,抛出 FormatException:
无法将参数值从 String 转换为 Int32。
内部异常是:
输入的字符串格式不正确。
我无法找出它反对的列,但唯一的 int 列(除了 PK)是 ActiveWorkRequestId。因此,Update 方法似乎将参数的空值视为空字符串,并试图将其强制转换为 int32,即使 table 列和参数都可为空。
为什么不能将列设置为空(特别是因为它在数据库中已经是空的)?
我能做些什么吗?
我也许应该提到该项目刚刚从 VS2003 (.NET 1.1) 导入到 VS2010 (.NET 4.0),一切正常。这就是为什么在代码中创建 SqlDataAdapter 而不是仅使用由 XSD 设计者创建的 TableAdapter - .NET 1.1 设计者没有创建 TableAdapter。 (如果可能的话,我不想重新生成所有 XSD)。
不使用 CopyCommandObject() 方法,而是使用:
da.UpdateCommand = cb.GetUpdateCommand().Clone();
这种方式更简单,更不容易出错。
我的 "User" table(SQL 服务器)有一个 (int,null) 列,ActiveWorkRequestId。 我正在尝试使用 SqlDataAdapter 更新 table。这是使用基于 XSD 强类型数据集定义 (Visual Studio 2010) 的默认更新命令的克隆设置的。所以命令看起来像
UPDATE [User] SET [Username] = @p1, [ActiveWorkRequestId] = @p2
WHERE (([Id] = @p3) AND ([Username] = @p4) AND ((@p5 = 1 AND
[ActiveWorkRequestId] IS NULL) OR ([ActiveWorkRequestId] = @p6)))
在此示例中,table "User" 有 3 列:Id、Username 和 ActiveWorkRequestId。参数 p2、p5 和 p6 都有关联的 ActiveWorkRequestId 列。
本例中更新命令(来自修改后的行)的运行时间参数是:
@p1 - "myusername"
@p2 - [DBNull]
@p3 - 126
@p4 - "myusername"
@p5 - [DBNull]
@p6 - [DBNull]
我得到所有更新的行(只有一个返回),然后更新如下。已更改行中的 ActiveWorkRequestId 为空(实际上与原始行中一样)。 "dt" 是我的数据集中填充的数据表。
// This part is inline for convenience, only done once in fact
// Some irrelevant code omitted
string query = String.Format("SELECT * FROM [{0}]", dt.TableName);
string sqlCon = ""; // connection string actually got from settings
SqlDataAdapter da = new SqlDataAdapter(query, sqlCon);
SqlCommandBuilder cb = new SqlCommandBuilder(da);
cb.QuotePrefix = "[";
cb.QuoteSuffix = "]";
da.UpdateCommand = CopyCommandObject(dt, cb.GetUpdateCommand());
// ... This part may execute more than once
DataRow[] foundRows = dt.Select("", "",
DataViewRowState.Added | DataViewRowState.ModifiedCurrent);
da.Update(foundRows); // Exception here
// ... defined elsewhere
private static SqlCommand CopyCommandObject(DataTable dt, SqlCommand cmd)
{
SqlCommand r = new SqlCommand(cmd.CommandText);
r.Connection = cmd.Connection;
foreach (SqlParameter p in cmd.Parameters)
{
DataColumn dc = dt.Columns[p.SourceColumn];
// Put this in since p.IsNullable always seems to be false
bool nullable = dc.AllowDBNull ? true : false;
SqlParameter newParam = new SqlParameter(
p.ParameterName,
p.SqlDbType,
p.Size,
p.Direction,
nullable,
p.Precision,
p.Scale,
p.SourceColumn,
p.SourceVersion,
p.Value);
r.Parameters.Add(newParam);
}
return (r);
}
当我在 SqlDataAdapter 上调用 Update 时,抛出 FormatException:
无法将参数值从 String 转换为 Int32。
内部异常是:
输入的字符串格式不正确。
我无法找出它反对的列,但唯一的 int 列(除了 PK)是 ActiveWorkRequestId。因此,Update 方法似乎将参数的空值视为空字符串,并试图将其强制转换为 int32,即使 table 列和参数都可为空。
为什么不能将列设置为空(特别是因为它在数据库中已经是空的)? 我能做些什么吗?
我也许应该提到该项目刚刚从 VS2003 (.NET 1.1) 导入到 VS2010 (.NET 4.0),一切正常。这就是为什么在代码中创建 SqlDataAdapter 而不是仅使用由 XSD 设计者创建的 TableAdapter - .NET 1.1 设计者没有创建 TableAdapter。 (如果可能的话,我不想重新生成所有 XSD)。
不使用 CopyCommandObject() 方法,而是使用:
da.UpdateCommand = cb.GetUpdateCommand().Clone();
这种方式更简单,更不容易出错。