无法批量插入Subsonic3,错误“必须声明标量变量...”

时间:2010-06-25 18:33:16

标签: activerecord 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模式将多个“Product”插入表“Products”。如果我逐个插入行,可以调用“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 :(得分:0)

我也遇到了这个问题。如果你查看它正在尝试运行的查询,你会看到它正在做这样的事情(这不是实际的代码,但你会明白这一点):

exec_sql N'insert into MyTable (SomeField) Values (@ins_SomeField)',N'@0 varchar(32)','@0=SomeValue'

由于某种原因,它使用"@ins_"+FieldName定义查询中的参数,但随后将参数作为序数传递。我还没有确定为什么/什么时候这样做的模式,但是我在这个开发周期中已经失去了足够的时间与SubSonic一起试图正确地诊断问题。

我实施的解决方法将涉及您从github下载3.0.0.4源代码并在Insert.cs的第179行进行更改。

读取的地方

ParameterName = _provider.ParameterPrefix + "ins_" + columnName.ToAlphaNumericOnly(),

将其更改为

ParameterName = _provider.ParameterPrefix + Inserts.Count.ToString(),

似乎为我做了伎俩。对于您,无论是明示的还是暗示的,我都不对此解决方案做出任何保证。它对我有用,但你的里程可能会有所不同。

我还应该注意到“更新”语句的相似逻辑以及第181和194行的Update.cs,但我还没有给我带来问题......但是。

老实说,我不认为SubSonic已准备好迎接黄金时段,这是一种耻辱,因为我真的很喜欢Rob如何设置它。也就是说,现在它在我的产品中变得更好或更差,所以你用你所拥有的东西做到最好。