4

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

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

错误发生在 bcp.WriteToServer(reader) 上,一直在寻找其他信息,但我仍然不知道是什么导致了问题,而且示例非常简单......而且我什至不知道名为name的参数来自哪里。

我的实际代码如下

        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

4 回答 4

2

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

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,它重新定义了 Supplier 对象中的“代码”和“名称”属性,这意味着阅读器无法映射到这些属性。我保留了修改案例中的属性,并修改了读取器参数列表以匹配,如第二行所示。

于 2017-02-02T12:07:02.597 回答
2

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

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

class ItemContainer { public A A; }


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"})

解决方案是将转储表更正为:

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 的混合类型,但对我们来说,我们知道它们是相同的类型(如果有的话)。

于 2018-03-26T07:53:28.233 回答
1

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

这是一个实际工作的示例,这个示例使用一个具体类作为其 POCO,并创建该 POCO 的通用列表,如下所示。

        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 在运行时无法正确读取 List 内的匿名/动态对象的属性时间(例如:看不到 MyColumn1 和 MyColumn2),即使它在那里。

所以这更像是一个限制

于 2015-03-13T18:25:22.860 回答
0

在我的情况下,这是由于列配置中有一个领先的空白空间。交叉检查列表中的所有 40 多列花了一个小时。注意:columnB 有前导空格。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);
        }
于 2018-04-10T03:31:46.307 回答