Использование AutoMapper для сопоставления IList <TSource>с (Iesi.Collections.Generic) ISet <TDestination> - PullRequest
8 голосов
/ 17 июля 2011

Я пытаюсь решить эту проблему в течение дня и не знаю, где, поэтому я надеюсь, что кто-то мог решить это раньше. Самым близким к решению, которое я нашел, было Как просто сопоставить NHibernate ISet с IList, используя AutoMapper и Сопоставить IList с ICollection через AutoMapper , но все равно не радость.

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

public class Parent
{
   public virtual ISet<Child> Children  {get; set; }
}

И бизнес-объект, который выглядит как:

public class ParentDto
{
   public IList<ChildDto> Children  {get; set; }
}

Использование AutoMapper для сопоставления данных с данными работает нормально:

...
Mapper.CreateMap<Parent, ParentDto>();
Mapper.CreateMap<Child, ChildDto>();
...

ParentDto destination = CWMapper.Map<Parent, ParentDto>(source);

Но когда я перехожу к отображению из бизнеса в данные, я получаю сообщение об ошибке:

...
Mapper.CreateMap<ParentDto, Parent>();
Mapper.CreateMap<ChildDto, Child>();
...

Parent destination = CWMapper.Map<ParentDto, Parent>(source);

Невозможно привести объект типа 'System.Collections.Generic.List' к '' Iesi.Collections.Generic.ISet '

Я добавил пользовательское сопоставление:

Mapper.CreateMap<ParentDto, Parent>()
      .ForMember(m => m.Children, o => o.MapFrom(s => ToISet<ChildDto>(s.Children)));

private static ISet<T> ToISet<T>(IEnumerable<T> list)
    {
        Iesi.Collections.Generic.ISet<T> set = null;

        if (list != null)
        {
            set = new Iesi.Collections.Generic.HashedSet<T>();

            foreach (T item in list)
            {
                set.Add(item);
            }
        }

        return set;
    }

Но я все еще получаю ту же ошибку. Любая помощь будет значительно сокращена!

Ответы [ 2 ]

7 голосов
/ 26 сентября 2011

Вы можете использовать функцию AfterMap () AutoMapper, например:

Mapper.CreateMap<ParentDto, Parent>()
      .ForMember(m => m.Children, o => o.Ignore()) // To avoid automapping attempt
      .AfterMap((p,o) => { o.Children = ToISet<ChildDto, Child>(p.Children); });

AfterMap () позволяет более детально контролировать некоторые важные аспекты обработки дочерних коллекций NHibernate (например, заменять содержимое существующих коллекций вместо перезаписи ссылки на коллекции, как в этом упрощенном примере).

2 голосов
/ 20 июля 2011

Это связано с тем, что параметры универсального типа источника и назначения не совпадают в свойствах источника и назначения, которые вы отображаете. Требуемое сопоставление составляет от IEnumerable<ChildDto> до ISet<Child>, которое можно обобщить до сопоставления от IEnumerable<TSource> до ISet<TDestination>, а не от IEnumerable<T> до ISet<T>. Вы должны принять это во внимание в вашей функции преобразования (на самом деле у вас есть правильный ответ в заголовке вашего вопроса ..).

Метод ToISet должен быть примерно таким, как опубликовано ниже. Он также использует AutoMapper для отображения ChildDto в Child.

private static ISet<TDestination> ToISet<TSource, TDestination>(IEnumerable<TSource> source)
{
    ISet<TDestination> set = null;
    if (source != null)
    {
        set = new HashSet<TDestination>();

        foreach (TSource item in source)
        {
            set.Add(Mapper.Map<TSource, TDestination>(item));
        }
    }
    return set;
}

Затем вы можете изменить определение карты следующим образом:

Mapper.CreateMap<ParentDto, Parent>().ForMember(m => m.Children,
          o => o.MapFrom(p => ToISet<ChildDto, Child>(p.Children)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...