Fastmember异常:指定的参数超出了有效值的范围。参数名称:名称

时间:2015-03-13 17:26:02

标签: sqlbulkcopy outofrangeexception fastmember

我遇到过这个错误 指定的参数超出了有效值的范围。参数名称:名称

当我几乎只是在这里复制示例时https://code.google.com/p/fast-member/

错误发生在bcp.WriteToServer(阅读器)上,一直在寻找其他信息,但我仍然不知道是什么原因引起了问题而且示例很简单...我甚至不知道参数名为 名称 来自。

我的实际代码在

之下
        using (var bcp = new SqlBulkCopy(configvalue1))
        using (var reader = ObjectReader.Create(DataToLoad, new string[]{"id","field1","field2","field3"}))
        {
            bcp.DestinationTableName = string.Format(DestinationTableFormat, DestinationDb, DestinationSchema, DestinationTable);
            bcp.BatchSize = BatchSize ?? 10000;
            bcp.WriteToServer(reader);
            bcp.Close();
        }

有人可以帮忙吗?

提前致谢

4 个答案:

答案 0 :(得分:0)

我相信我现在知道为什么会这样。

这是一个实际有效的例子,这个例子使用一个具体的类作为它的POCO,并创建一个POCO的通用List,如下所示。

        IList<MyClass> ls = new List<MyClass>();
        ls.Add(new MyClass { MyColumn1 = "The", MyColumn2 = "Test2" });
        ls.Add(new MyClass { MyColumn1 = "Big", MyColumn2 = "Test2" });
        ls.Add(new MyClass { MyColumn1 = "Ant", MyColumn2 = "Test2" });
        DataTable dt = new DataTable();
        using (var reader = ObjectReader.Create(ls))
        {
            dt.Load(reader);
        }

这个更像是您实时分配属性的匿名对象列表。

        IList<object> ls2 = new List<object>();
        ls2.Add(new { MyColumn1 = "The", MyColumn2="Test2" });
        ls2.Add(new { MyColumn1 = "Big", MyColumn2="Test2" });
        ls2.Add(new { MyColumn1 = "Ant", MyColumn2="Test2" });
        DataTable dt2 = new DataTable();
        using (var reader2 = ObjectReader.Create(ls2))
        {
            dt2.Load(reader2);
        }

这也不起作用

        IList<dynamic> ls3 = new List<dynamic>();
        ls3.Add(new { MyColumn1 = "The", MyColumn2 = "Test2" });
        ls3.Add(new { MyColumn1 = "Big", MyColumn2 = "Test2" });
        ls3.Add(new { MyColumn1 = "Ant", MyColumn2 = "Test2" });
        DataTable dt3 = new DataTable();
        using (var reader3 = ObjectReader.Create(ls3))
        {
            dt3.Load(reader3);
        }

即使3个列表在功能上相同,一个是POCO列表,一个是匿名对象列表,一个是动态成员列表,FASTMEMBER无法正确读取内部匿名/动态对象的属性。在运行时列出(例如:CANT查看MyColumn1和MyColumn2),即使它在那里。

所以这更多是一种限制

答案 1 :(得分:0)

对我来说,这是由源数据对象上的属性名称与阅读器创建步骤中的参数列表不匹配引起的。

class Supplier
{
    public string Code;
    public string Name;
}

// version that caused the error 
using (var rdr = ObjectReader.Create(suppliers, "code", "name"))

// compared to re-cased version to match the Supplier object property casing
using (var rdr = ObjectReader.Create(suppliers, "Code", "Name"))

我曾经使用过Re-sharper来重新设置&#34;代码&#34;和&#34;名称&#34;供应商对象中的属性,这意味着读者无法映射到属性。我在修改后的案例中保留了属性,并修改了阅读器参数列表以匹配,如第二行所示。

答案 2 :(得分:0)

对我们来说,这是由泛型和继承的结合引起的

abstract class A { public string A; }
class B : A { public string B; }

class ItemContainer { public A A; }


private async Task DumpDataToTable<T>(IEnumerable<T> items, string tableName, string[] properties)
{
    using (var sqlCopy = new SqlBulkCopy(AC.OpenConnection))
    {
        sqlCopy.DestinationTableName = tableName;

        using (var reader = ObjectReader.Create(items, properties))
            await sqlCopy.WriteToServerAsync(reader);
    }
}

IEnumerable<ItemContainer> items = ....    
var manyAs = items.Select(item => item.A);

// here generic type parameter is `A`, and it doesn't contain `B`
await DumpDataToTable(manyAs, "#temptable", new[]{"A", "B"})

解决方案是将dumptable更正为:

private async Task DumpDataToTable<T>(IEnumerable<T> items, string tableName, string[] properties)
{
    using (var sqlCopy = new SqlBulkCopy(AC.OpenConnection))
    {
        sqlCopy.DestinationTableName = tableName;
        sqlCopy.BatchSize = 500;

        var item = items.FirstOrDefault();
        if (item == null)
            return;

        using (var reader = new ObjectReader(item.GetType(), items, properties))
            await sqlCopy.WriteToServerAsync(reader);
    }
}

这不会处理ItemContainer.A的混合类型,但对我们来说,我们知道它们是相同的类型(如果有的话)。

答案 3 :(得分:0)

在我的情况下,这是由于列配置中的前导空格。花了一个多小时来检查列表中的所有40多列。 注意:columnB具有领先的spaec。 columnC具有尾随空格。检查案例。

var columns = new string [] {“columnA”,“columnB”,“columnC”};

        using (var bcp = new SqlBulkCopy(connStr))
        using (var reader = ObjectReader.Create(newItems.ToList(), columns))
        {
            bcp.DestinationTableName = "targetTable1";
            bcp.WriteToServer(reader);
        }