Исключение быстрого члена: указанный аргумент находится вне диапазона допустимых значений. Имя параметра: имя
Я столкнулся с этой ошибкой. Указанный аргумент вышел за пределы допустимых значений. Имя параметра: имя
Когда я почти просто копирую пример здесь, 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);
}