Не удалось выполнить пакетную вставку в Subsonic3 с ошибкой «Необходимо объявить скалярную переменную ...» - PullRequest
4 голосов
/ 25 июня 2010

Я столкнулся с проблемой вставки нескольких строк в пакет с помощью 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 Ответ

0 голосов
/ 30 июня 2010

Я тоже столкнулся с этой проблемой.Если вы посмотрите на запрос, который он пытается выполнить, то увидите, что он выполняет что-то вроде этого (это не настоящий код, но вы поймете, что он имеет смысл):

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

...