5

I have a Person table with following column names:

Id, Name, Dob

I also have a poco as:

public class Person
{
    public int Id {get; set;}
    public string Name {get; set;}
    public string DateOfBirth {get; set;}
}

I am then trying:

var people = new List<Person>();
... // added a bunch of people

using (var bcp = new SqlBulkCopy(sqlConnection, SqlBulkCopyOptions.TableLock, transaction))
using (var reader = ObjectReader.Create(people, "Id", "Name", "Dob"))
{
    bcp.BulkCopyTimeout = 120;
    bcp.BatchSize = 0;
    bcp.DestinationTableName = "Person";
    bcp.WriteToServer(reader);
}

However since Column name Dob does not match the property name DateOfBirth I get an Index out of range thrown by FastMember, how can I solve the problem without having to rename the property or the column.

Please note that I need an answer which can work with both property and column names only known at run time as I am currently using ServiceStack Ormlite to retrieve the table metadata at runtime and FastMember to tap into the ObjectReader again at runtime.

Any help is much appreciated.

MaYaN
  • 6,683
  • 12
  • 57
  • 109

2 Answers2

9

At the end it turned out to be much simpler than I thought:

// Get valid columns from the [targetTable] on the db at runtime
// and produce a simple mapping
// validColumns is an IDictionary<string, string>
var membersExposedToReader = validColumns.Keys.ToArray();

// data is an IEnumerable<T>           
using (var bcp = new SqlBulkCopy(sqlConnection, SqlBulkCopyOptions.TableLock, tran))
using (var reader = ObjectReader.Create(data, membersExposedToReader))
{
    foreach (var member in membersExposedToReader)
    {
        bcp.ColumnMappings.Add(member, validColumns[member]);
    }

    bcp.BulkCopyTimeout = 120;
    bcp.BatchSize = 0;
    bcp.DestinationTableName = targetTable;
    bcp.WriteToServer(reader);
}
MaYaN
  • 6,683
  • 12
  • 57
  • 109
1

With a simple LINQ projection you could do:

var people2 = people.Select(x => new { x.Id, x.Name, Dob = x.DateOfBirth });

and then

using (var reader = ObjectReader.Create(people2, "Id", "Name", "Dob"))
xanatos
  • 109,618
  • 12
  • 197
  • 280