Исключение быстрого члена: указанный аргумент находится вне диапазона допустимых значений. Имя параметра: имя

Я столкнулся с этой ошибкой. Указанный аргумент вышел за пределы допустимых значений. Имя параметра: имя

Когда я почти просто копирую пример здесь, 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 ответа

Для меня это было вызвано несоответствием между именами свойств в исходном объекте данных и списком параметров на этапе создания читателя.

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, который изменяет регистр свойств "код" и "имя" в объекте "Поставщик", и это означает, что читатель не может сопоставить свойства. Я оставил свойства в пересмотренном случае и изменил список параметров считывателя, чтобы он соответствовал, как показано во второй строке.

Для нас это было вызвано сочетанием дженериков и наследования

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

Решение состояло в том, чтобы исправить самосвал для:

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, но для нас мы знаем, что они одного типа, если таковые имеются.

Я верю, что теперь я знаю, почему это происходит.

Это пример, который действительно работает, этот использует конкретный класс в качестве своего 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);
        }

Несмотря на то, что три списка функционально одинаковы: один список POCO, один список анонимных объектов, один список динамических членов, FASTMEMBER не может правильно прочитать свойства анонимного / динамического объекта внутри списка при запуске. время (например: CANT SEE THE MyColumn1 и MyColumn2), даже если оно есть.

Так что это скорее ограничение

В моем случае это связано с пустым пробелом в конфигурации столбца. Потребовался час, чтобы перепроверить все 40+ столбцов в списке. Примечание: колонка B имеет ведущий spaec. columnC имеет завершающий пробел. Проверьте дело также.

var columns = новая строка [] { "columnA", " columnB", "columnC " };

        using (var bcp = new SqlBulkCopy(connStr))
        using (var reader = ObjectReader.Create(newItems.ToList(), columns))
        {
            bcp.DestinationTableName = "targetTable1";
            bcp.WriteToServer(reader);
        }
Другие вопросы по тегам