5

我有一个Person包含以下列名称的表:

身份证、姓名、出生日期

我也有一个 poco:

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

然后我正在尝试:

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

但是,由于列名Dob与属性名不匹配,DateOfBirth我得到了Index out of rangeFastMember 抛出的问题,我怎样才能解决问题而不必重命名属性或列。

请注意,我需要一个可以使用仅在运行时知道的属性和列名的答案,因为我目前正在使用 ServiceStack Ormlite 在运行时检索表元数据,并使用 FastMember 在运行时再次访问 ObjectReader。

任何帮助深表感谢。

4

2 回答 2

9

最后发现它比我想象的要简单得多:

// 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);
}
于 2015-03-18T22:08:53.557 回答
1

使用简单的 LINQ 投影,您可以执行以下操作:

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

进而

using (var reader = ObjectReader.Create(people2, "Id", "Name", "Dob"))
于 2015-03-18T16:57:29.950 回答