Не удалось выполнить пакетную вставку в 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 ».»

Пожалуйста, помогите мне решить эту проблему. Большое спасибо.


person cheka    schedule 25.06.2010    source источник


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

person andymeadows    schedule 30.06.2010
comment
Я загрузил образец кода, чтобы проиллюстрировать эту проблему на github.com/andymeadows/SubSonic-Defect-Help < / а> - person andymeadows; 13.07.2010