我的用户" table(SQL Server)有一个(int,null)列,ActiveWorkRequestId。 我正在尝试使用SqlDataAdapter更新表。这是基于XSD强类型数据集定义(Visual Studio 2010)的默认Update命令的克隆设置的。所以命令看起来像
UPDATE [User] SET [Username] = @p1, [ActiveWorkRequestId] = @p2
WHERE (([Id] = @p3) AND ([Username] = @p4) AND ((@p5 = 1 AND
[ActiveWorkRequestId] IS NULL) OR ([ActiveWorkRequestId] = @p6)))
在此示例中,表格为#34; User"有3列:Id,Username和ActiveWorkRequestId。参数p2,p5和p6都有一个关联的ActiveWorkRequestId列。
此示例中更新命令(来自修改行)的运行时参数为:
@p1 - "myusername"
@p2 - [DBNull]
@p3 - 126
@p4 - "myusername"
@p5 - [DBNull]
@p6 - [DBNull]
我获得了所有更新的行(只返回了一行),然后按如下方式更新。更改行中的ActiveWorkRequestId为null(实际上就像在原始行中一样)。 " DT"是我的DataSet中填充的DataTable。
// 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,即使表列和参数都可以为空。
为什么不能将列设置为null(特别是因为它在数据库中已经为null)? 我可以对此做些什么吗?
我或许应该提一下,该项目刚刚从VS2003(.NET 1.1)导入VS2010(.NET 4.0),在那里一切正常。这就是为什么SqlDataAdapter是用代码创建的,而不是仅仅使用由XSD设计器创建的TableAdapter - .NET 1.1设计器没有创建TableAdapter。 (如果可能的话,我不想重新生成所有的XSD。)
答案 0 :(得分:1)
使用:
而不是使用CopyCommandObject()方法da.UpdateCommand = cb.GetUpdateCommand().Clone();
这种方式更简单,更不容易出错。