Не удалось выполнить пакетную вставку в Subsonic3 с ошибкой "Необходимо объявить скалярную переменную..."
Я столкнулся с проблемой вставки нескольких строк в пакет с помощью Subsonic3. Моя среда разработки включает в себя:
1. Visual Studio 2010, but use .NET 3.5
2. Active Record Mode in SubSonic 3.0.0.4
3. SQL Server 2005 express
4. Northwind sample database
Я использую режим Active Reecord, чтобы вставить несколько "Продукт" в таблицу "Продукты". Если я вставляю строки по одной, либо вызываю "aProduct.Add()", либо вызываю "Insert.Execute()" несколько раз (как и приведенные ниже коды), все работает нормально.
private static Product[] CreateProducts(int count)
{
Product[] products = new Product[count];
for (int index = 0; index < products.Length; ++index)
{
products[index] = new Product
{
ProductName = string.Format("cheka-test-{0}", index.ToString()),
Discontinued = (index % 2 == 0),
};
}
return products;
}
private static void SucceedByMultiExecuteInsert()
{
Product[] products = CreateProducts(2);
// -------------------------------- prepare batch
NorthwindDB db = new NorthwindDB();
var inserts = from prod in products
select db.Insert.Into<Product>(x => x.ProductName, x => x.Discontinued).Values(prod.ProductName, prod.Discontinued);
// -------------------------------- batch insert
var selectAll = Product.All();
Console.WriteLine("--- before total rows = {0}", selectAll.Count().ToString());
foreach (Insert insert in inserts)
insert.Execute();
Console.WriteLine("+++ after inserting {0} rows, now total rows = {1}",
products.Length.ToString(), selectAll.Count().ToString());
}
но если я использую "BatchQuery", как коды ниже,
private static void FailByBatchInsert()
{
Product[] products = CreateProducts(2);
// -------------------------------- prepare batch
NorthwindDB db = new NorthwindDB();
BatchQuery batchquery = new BatchQuery(db.Provider, db.QueryProvider);
var inserts = from prod in products
select db.Insert.Into<Product>(x => x.ProductName, x => x.Discontinued).Values(prod.ProductName, prod.Discontinued);
foreach (Insert insert in inserts)
batchquery.Queue(insert);
// -------------------------------- batch insert
var selectAll = Product.All();
Console.WriteLine("--- before total rows = {0}", selectAll.Count().ToString());
batchquery.Execute();
Console.WriteLine("+++ after inserting {0} rows, now total rows = {1}",
products.Length.ToString(), selectAll.Count().ToString());
}
затем произошла ошибка с исключением: " Необработанное исключение: System.Data.SqlClient.SqlException: необходимо объявить скалярную переменную"@ins_ProductName". Необходимо объявить скалярную переменную"@ins_ProductName". "
Пожалуйста, помогите мне решить эту проблему. Большое спасибо.
1 ответ
Я столкнулся с этой проблемой также. Если вы посмотрите на запрос, который он пытается выполнить, вы увидите, что он делает что-то вроде этого (это не настоящий код, но вы поймете, что нужно):
exec_sql N'insert into MyTable (SomeField) Values (@ins_SomeField)',N'@0 varchar(32)','@0=SomeValue'
По какой-то причине он определяет параметры в запросе с "@ins_"+FieldName
но затем передает параметры как порядковые номера. Мне еще предстоит определить схему, почему / когда это происходит, но я потерял достаточно времени во время этого цикла разработки с SubSonic, чтобы попытаться правильно диагностировать проблему.
Обходное решение, которое я реализовал, включает в себя загрузку исходного кода 3.0.0.4 с github и внесение изменений в строку 179 файла Insert.cs.
Где это читает
ParameterName = _provider.ParameterPrefix + "ins_" + columnName.ToAlphaNumericOnly(),
Меняя его на
ParameterName = _provider.ParameterPrefix + Inserts.Count.ToString(),
казалось, добился цели для меня. Я не даю никаких гарантий относительно этого решения для вас, явных или подразумеваемых. Это сработало для меня, но ваш пробег может отличаться.
Я должен также отметить, что есть аналогичная логика в выражениях "update" также в Update.cs в строках 181 и 194, но у меня их не было, но это вызывает проблемы... пока.
Честно говоря, я не думаю, что SubSonic готов к прайм-тайму, и это позор, потому что мне действительно нравится, как Роб настроил это. Тем не менее, это в моем продукте в лучшую или худшую сторону, поэтому вы делаете лучшее с тем, что у вас есть.