Пользовательское преобразование типов с AutoMapper.Data - PullRequest
0 голосов
/ 22 октября 2018

Мое приложение читает из базы данных Sql Server или Oracle.

Большинство запросов очень просты, и в большинстве случаев нет разницы в семантике запросов.Я решил не использовать наборы данных, а непосредственно преобразовывать результаты в DTO:

SomeDto data = GetResult<SomeDto>("SELECT * FROM table");

В методе GetResult я использую AutoMapper с расширениями AutoMapper.Data.Ниже приведено упрощенное содержание метода GetResult.

public IEnumerable<T> GetResult(string query) 
{
    using(DbConnection db = GetConnection()) 
    {
        var command = db.CreateCommand()
        command.CommandText = query;

        return mapper.map<IDataReader, IEnumerable<T>>(dataReader);
    }
}

Благодаря расширениям AutoMapper.Data я могу преобразовать устройство чтения данных непосредственно в DTO с помощью конфигурации автоматического устройства.

cfg.AddDataReaderMapping();

Проблема

База данных Oracle и Sql Server имеет одинаковую структуру, но есть некоторые несоответствия в типах столбцов.

Например, Oracle NUMBER(8) интерпретируется как int, а Sql Server NUMBER(8,0) интерпретируется как decimal, хотя это действительно всегда целое число (да, это должно быть int, но я не могуделать что-нибудь с этим).Если целевой тип в DTO не соответствует, генерируется исключение несоответствия типов.

public class SomeDto 
{
     //works fine with Oracle
     //throws exception when using Sql Server
     public int ID { get; set; }
}

Я не могу изменить типы базы данных, и я ожидаю, что появятся другие подобные несоответствия, поэтому я решил, что я сконфигурировал автопроизводитель.

Что-то вроде:

  • , если свойство DTO имеет тип X, а значение, присвоенное ему, имеет определенный тип, используйте это явное преобразование.

Например

mapper.map<IDataReader, IEnumerable<T>>(dataReader, options => {
    options.ConfigureMap()
            //simple explicit cast, no loss of precision expected
           .UseThisCastWhenMappingToDTO<decimal, int>(decimalInput => (int)decimalInput);
});

Вопрос

Можно ли сказать что-то вроде UseThisCastWhenMappingToDTO<TSource, TTarget> с AutoMapper?

Потому что, похоже, это возможно, но я понятия не имею, как это сделать.Я не смог найти никакой документации или примеров того, как можно указать пользовательскую конфигурацию при сопоставлении IDataReader с IEnumerable<T>.

...