В моей таблице «Пользователь» (SQL Server) есть столбец (int, null), ActiveWorkRequestId. Я пытаюсь обновить таблицу с помощью SqlDataAdapter. Это настроено с клоном команды обновления по умолчанию, основанной на определении строго типизированного набора данных XSD (Visual Studio 2010). Таким образом, команда выглядитФорматException из SQLDataAdapter.Update, вызванный нулевым значением
UPDATE [User] SET [Username] = @p1, [ActiveWorkRequestId] = @p2
WHERE (([Id] = @p3) AND ([Username] = @p4) AND ((@p5 = 1 AND
[ActiveWorkRequestId] IS NULL) OR ([ActiveWorkRequestId] = @p6)))
В этом примере в таблице «Пользователь» имеет 3 колонки: Id, имя пользователя и ActiveWorkRequestId. Параметры p2, p5 и p6 имеют связанный столбец ActiveWorkRequestId.
параметры во время выполнения для команды обновления (из модифицированной строки) в этом примере:
@p1 - "myusername"
@p2 - [DBNull]
@p3 - 126
@p4 - "myusername"
@p5 - [DBNull]
@p6 - [DBNull]
Я получаю все обновленные строки (есть только один вернулся), а затем обновить следующим образом. ActiveWorkRequestId в измененной строке имеет значение NULL (как это было в исходной строке). «dt» - это заполненный DataTable из моего DataSet.
// 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, FormatException брошено:
Не удалось преобразовать значение параметра из строки к Int32.
Внутреннее исключение:
Входная строка не была в правильном формате.
Я не могу узнать, в каком столбце он выступает, но единственным столбцом int (кроме ПК) является ActiveWorkRequestId. Таким образом, кажется, что метод Update обрабатывает значение null для параметра как пустую строку и пытается принудить его к int32, даже если столбец таблицы и параметр являются обнуляемыми.
Почему он не может просто установить столбец в нуль (тем более, что он уже равен нулю в базе данных)? Могу ли я что-нибудь сделать?
Возможно, мне стоит упомянуть, что проект был просто импортирован в VS2010 (.NET 4.0) из VS2003 (.NET 1.1), где все работало нормально. Вот почему SqlDataAdapter создается в коде, а не только с помощью TableAdapter, созданного дизайнером XSD - конструктор .NET 1.1 не создал TableAdapters. (Я не хочу, если возможно, регенерировать все XSD).
Похоже, что-то может пытаться присвоить строку «NULL» или «DbNull» как значение параметра вместо экземпляра DbNull.Value. –
Строка DataTable определенно содержит DbNull.Value, поэтому, если это неверно расширено для параметра запроса, то это не ошибка в ADO.NET? В этом процессе нет кода пользователя. Если это происходит для всех, кто пытается обновить значение NULL int, дату/время и т. Д. С помощью null, используя SqlDataAdapter, то почему Интернет не заполнен людьми, жалующимися на это? –
Похоже, что это давняя проблема, которую Microsoft не намерена решать ... см., Например, [эта ссылка] (http://forums.asp.net/t/1227689.aspx). Я могу попробовать расширение VS, упомянутое там, так как кажется невозможным использовать SqlDataAdapter для обновления, где задействуются нулевые столбцы, отличные от строки. –