Emit Mapper Flattering и несоответствие названий свойств

Как сопоставить класс пользователя с классом UserModel с помощью Emit Mapper?

    public class User
    {
        public Guid Id { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public IList<Role> Roles { get; set; }

        public Company Company { get; set; }        
    }

    public class UserModel
    {
        public Guid Id { get; set; }

        public Guid CompanyId { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }      

        public IList<RoleModel> Roles { get; set; }
}

Есть несколько проблем:

  • Мне нужно сгладить объект так, чтобы у меня был CompanyId вместо объекта Company.
  • У объекта Company есть свойство Id, в UserModel у меня есть CompanyId, который соответствует идентификатору компании, но имена свойств не совпадают.
  • Мне нужно сопоставить List<Role> с List<RoleModel>

person petrov.alex    schedule 08.03.2012    source источник
comment
У меня похожая проблема ... Вы ее решили?   -  person fra    schedule 17.05.2012


Ответы (2)


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

Источник

public class SourceObject
{
public SourceSubObject SomeClass { get; set; }
}

public SourceSubObject
{
    public int Age { get; set; }
}

Цель

public class Target
{
public int SomeClassAge  { get; set; }
}

Во-вторых, один из вариантов - позволить настройкам по умолчанию копировать те свойства, которые он может копировать, а все остальное делать вручную.

var target = ObjectMapperManager.DefaultInstance.GetMapper<Source, Target>().Map(source);
target.CompanyId = target.Company.CompanyId;

Или, если вам нужно повторно использовать сопоставление, создайте настраиваемый сопоставитель

Пользовательский картограф

private Target Converter(Source source)
{
   var target = new Target();
   target.CompanyId = source.Company.CompanyId;
   return target;
}

Использование

var mapper = new DefaultMapConfig().ConvertUsing<Source, Target>(Converter);
var target = ObjectMapperManager.DefaultInstance.GetMapper<Source, Target>(mapper).Map(source);

Обновить

Что происходит с сопоставлением Role & RoleModel. Кажется, что в этом случае вам нужно включить Deep copy, и в зависимости от определений классов вы можете либо скопировать его напрямую, либо выполнить какое-то настраиваемое сопоставление.

ObjectMapperManager.DefaultInstance.GetMapper<Source, Target>(new DefaultMapConfig().DeepMap<ClassToDeepMap>().DeepMap<ClassToDeepMap>()).Map(source, target);
person Tx3    schedule 09.03.2012

  • Для пользы я использовал конфигурацию из примеров в исходных файлах Emit Mapper: http://emitmapper.codeplex.com/SourceControl/changeset/view/69894#1192663

  • Чтобы имена совпадали, в классе Company должно быть поле с именем Id

  • Для отображения List<Role> в List<RoleModel> я использовал собственный конвертер:

    public class EntityListToModelListConverter<TEntity, TModel>
    {
        public List<TModel> Convert(IList<TEntity> from, object state)
        {
            if (from == null)
                return null;
    
            var models = new List<TModel>();
            var mapper = ObjectMapperManager.DefaultInstance.GetMapper<TEntity, TModel>();
    
            for (int i = 0; i < from.Count(); i++)
            {
                models.Add(mapper.Map(from.ElementAt(i)));
            }
    
            return models;
        }
    }
    

    Итак все вместе:

     var userMapper = ObjectMapperManager.DefaultInstance.GetMapper<User, UserModel>( 
                 new FlatteringConfig().ConvertGeneric(typeof(IList<>), typeof(IList<>), 
                 new DefaultCustomConverterProvider(typeof(EntityListToModelListConverter<,>))));
    
  • Возникла проблема при использовании конфигурации Flatterning с пользовательскими преобразователями, проверьте мой вопрос: Emit Mapper Flattering с Пользовательские преобразователи

person petrov.alex    schedule 17.05.2012
comment
Спасибо, это решило мою проблему. В любом случае, мне все еще не ясно, как я должен указать способ сопоставления TEntity и TModel ... Предположим, у меня есть тип A с коллекцией типа B, и я хотел бы сопоставить его с AMapped с набором BMapped ... как мне настроить конфигурацию? я должен использовать PostProcess? Мне очень нравится идея этой библиотеки, но в ней очень не хватает конфигураций и примеров ... - person fra; 19.05.2012
comment
Это зависит от типа коллекции. В моем примере у меня есть общая коллекция, поэтому я использовал настраиваемый конвертер для общих типов emitmapper.codeplex.com/. Вам необходимо предоставить собственный конвертер для преобразования из B в BMapped, в случае дженериков вы зарегистрируете его как new FlatteringConfig().ConvertGeneric(typeof(B), typeof(BMapped), new DefaultCustomConverterProvider(typeof(CustomConverterClass))) - person petrov.alex; 19.05.2012
comment
В методе Convert я сопоставляю каждый элемент Role с RoleModel, создавая сопоставитель, такой как var mapper = ObjectMapperManager.DefaultInstance.GetMapper<TEntity, TModel>();, а затем вызываю метод Map для каждого элемента и добавляю возвращаемое значение в коллекцию моделей. - person petrov.alex; 19.05.2012
comment
Большое Вам спасибо. Я понял это лучше и начинаю извлекать из этого выгоду. - person fra; 20.05.2012
comment
И последнее: это объект FlatteringConfig, который вы использовали? Я не мог его найти. - person fra; 20.05.2012
comment
Я скачал его отдельно с CodePlex, проверьте ссылку в моем ответе (первая). Это прямая ссылка на этот файл. Также проверьте последнюю ссылку в моем ответе, так как возникла проблема использования этой конфигурации с пользовательскими преобразователями. - person petrov.alex; 20.05.2012
comment
EmitMapper не работает при использовании коллекций с типизированным интерфейсом. Либо вам нужно настроить его, либо вы должны использовать конкретный список вместо интерфейса, что, на мой взгляд, нехорошо ... FastMapper делает это, хотя и AutoMapper, хотя AutoMapper имеет проблемы с производительностью и не является моим любимым! - person DAG; 27.12.2015