Знам, че тази публикация е стара, но се натъкнах на същия проблем и най-накрая измислих решение, за да определя коя колона причинява проблема и да го докладвам отново, ако е необходимо. Установих, че colid
върнат в SqlException не е базиран на нула, така че трябва да извадите 1 от него, за да получите стойността. След това се използва като индекс на _sortedColumnMappings
ArrayList на екземпляра на SqlBulkCopy, а не индексът на съпоставянията на колони, които са добавени към екземпляра на SqlBulkCopy. Едно нещо, което трябва да се отбележи е, че SqlBulkCopy ще спре при първата получена грешка, така че това може да не е единственият проблем, но поне помага да го разберете.
try
{
bulkCopy.WriteToServer(importTable);
sqlTran.Commit();
}
catch (SqlException ex)
{
if (ex.Message.Contains("Received an invalid column length from the bcp client for colid"))
{
string pattern = @"\d+";
Match match = Regex.Match(ex.Message.ToString(), pattern);
var index = Convert.ToInt32(match.Value) -1;
FieldInfo fi = typeof(SqlBulkCopy).GetField("_sortedColumnMappings", BindingFlags.NonPublic | BindingFlags.Instance);
var sortedColumns = fi.GetValue(bulkCopy);
var items = (Object[])sortedColumns.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sortedColumns);
FieldInfo itemdata = items[index].GetType().GetField("_metadata", BindingFlags.NonPublic | BindingFlags.Instance);
var metadata = itemdata.GetValue(items[index]);
var column = metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
var length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
throw new DataFormatException(String.Format("Column: {0} contains data with a length greater than: {1}", column, length));
}
throw;
}