Не удалось выполнить пакетную вставку в 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 готов к прайм-тайму, и это позор, потому что мне действительно нравится, как Роб настроил это. Тем не менее, это в моем продукте в лучшую или худшую сторону, поэтому вы делаете лучшее с тем, что у вас есть.

Другие вопросы по тегам