Я могу настроить AutoMapper для чтения из имен пользовательского столбца при отображении от IDataReader?

Код Psuedo для отображения конфигурации (как ниже) не возможен, так как лямбда только позволяет нам тип доступа 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().

5
задан Omu 21 May 2011 в 08:35
поделиться

1 ответ

Я не знаю об автоматическом преобразователе, но я сопоставляю устройство чтения данных с объектами с помощью ValueInjecter следующим образом:

 while (dr.Read())
 {
    var o = new User();
    o.InjectFrom<DataReaderInjection>(dr);
    return o;
 }

и DataReaderInjection (что-то вроде ValueResolver для Automapper)

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 в любой тип объекта


Хорошо, в соответствии с вашими требованиями, я думаю, это должно быть так:
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, как вы и хотели :)


хорошо, если вы хотите передать что-то в инъекцию, вы можете сделать это разными способами, вот как:
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(
...
3
ответ дан 15 December 2019 в 06:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: