无法使用用于映射配置的伪代码(如下所示),因为lambda仅允许我们访问Type IDataReader,在实际映射时,AutoMapper将进入每个IDataRecord
的每个“单元”,而IDataReader.Read() == true
:
var mappingConfig = Mapper.CreateMap<IDataReader, IEnumerable<MyDTO>>();
mappingConfig.ForMember(
destination => destination.???,
options => options.MapFrom(source => source.???));
任何人都可以想到一种在运行时使用AutoMapper配置执行此操作的方法,或仅使用满足以下要求的其他一些动态方法来执行此操作。
要求是支持任何传入的
IDataReader
,其列名称可能与MyDTO
的属性名称不匹配,并且没有我可以依赖的命名约定。相反,我们将要求用户在运行时通过IDataReader
将期望的列名与在IDataReader.GetSchemaTable()
中找到的实际列名进行交叉引用。 最佳答案
我不了解自动映射器,但是我正在使用ValueInjecter将datareader映射到对象,如下所示:
while (dr.Read())
{
var o = new User();
o.InjectFrom<DataReaderInjection>(dr);
return o;
}
和DataReaderInjection(类似于AutoMapper的ValueResolver)
public class DataReaderInjection : KnownSourceValueInjection<IDataReader>
{
protected override void Inject(IDataReader source, object target, PropertyDescriptorCollection targetProps)
{
for (var i = 0; i < source.FieldCount; i++)
{
var activeTarget = targetProps.GetByName(source.GetName(i), true);
if (activeTarget == null) continue;
var value = source.GetValue(i);
if (value == DBNull.Value) continue;
activeTarget.SetValue(target, value);
}
}
}
您可以使用此方法将IDataReader中的值注入(inject)到对象的任何类型
好的,所以根据您的要求,我想应该是这样的:
public class DataReaderInjection : KnownSourceValueInjection<IDataReader>
{
protected override void Inject(IDataReader source, object target, PropertyDescriptorCollection targetProps)
{
var columns = source.GetSchemaTable().Columns;
for (var i = 0; i < columns.Count; i++)
{
var c = columns[i];
var targetPropName = c.ColumnName; //default is the same as columnName
if (c.ColumnName == "Foo") targetPropName = "TheTargetPropForFoo";
if (c.ColumnName == "Bar") targetPropName = "TheTargetPropForBar";
//you could also create a dictionary and use it here
var targetProp = targetProps.GetByName(targetPropName);
//go to next column if there is no such property in the target object
if (targetProp == null) continue;
targetProp.SetValue(target, columns[c.ColumnName]);
}
}
}
在这里,我使用了GetSchemaTable,就像您想要的一样:)
好的,如果您想将一些东西传递给注入(inject),您可以通过多种方式进行操作,方法如下:
o.InjectFrom(new DataReaderInjection(stuff), dr);
//you need a constructor with parameters for the DataReaderInjection in this case
var ri = new DataReaderInjection();
ri.Stuff = stuff;
o.InjectFrom(ri, dr);
//you need to add a property in this case
这是一个提示(针对带参数方式的构造函数)
public class DataReaderInjection : KnownSourceValueInjection<IDataReader>
{
private IDictionary<string, string> stuff;
public DataReaderInjection(IDictionary<string,string> stuff)
{
this.stuff = stuff;
}
protected override void Inject(
...
关于c# - 从IDataReader映射时,可以将AutoMapper配置为从自定义列名称读取吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3061369/