AutoMapper: невозможно преобразовать объект типа 'System.Linq.Expressions.MethodCallExpressionN' в тип 'System.Linq.Expressions.MemberExpression'

Из того, что я прочитал об этой ошибке, f.E. здесь: Почему одни свойства объекта UnaryExpression, а другие MemberExpression?

Это происходит, когда объект ожидается, но возвращается тип значения, поэтому среда CLR должна упаковать это, что является еще одним (унарным) выражением.

Что меня действительно беспокоит, следующее AutoMapper-Mapping работает без проблем:

.ForMember(d => d.IndividualId, c => c.MapFrom(f => f.Individual.Id));

Это не работает только тогда, когда Mapping-Expression имеет другое выражение, которое возвращает Тип значения:

.ForMember(d =>
    d.IndividualId, c => c.MapFrom(f =>
        f.Individuals.First(d => d.Individual.Name == "Test").Id
    ));

Я написал этот пример, чтобы показать, что я хотел бы сделать, поэтому он может быть не на 100% подходящим? Я просто не могу отстать, почему первое выражение не вызывает этого исключения, потому что в обоих случаях должна произойти упаковка?

Редактировать

Ответ Итвана также работает, цель - просто устранить необходимость в упаковке. Это тоже работает примерно так:

m => m.MapFrom(f =>
    f.Individuals.Where(ms => ms.Individual.Name == name)
    .Select(i => i.Individual.Id).FirstOrDefault()
)

person Matthias Müller    schedule 11.06.2015    source источник
comment
Выглядит вполне законно. Второй - не собственность. AutoMapper предназначен для отображения свойств одного объекта на свойства другого класса. Также делаю это, написав эффективный IL. Вы вызываете метод LinqToObject (который явно не является свойством). Как AutoMapper меняет сопоставления?   -  person Aron    schedule 11.06.2015
comment
Ну, поскольку он работает со ссылочными типами, я думаю, что это вообще возможно. Интересная часть может заключаться в том, где он упаковывает вещи и можно ли ему явно сказать, какой тип брать, чтобы ему не приходилось собирать вещи.   -  person Matthias Müller    schedule 12.06.2015
comment
Нет ... как вы измените метод first?   -  person Aron    schedule 12.06.2015
comment
Извините, я не понимаю, о чем вы спрашиваете: |   -  person Matthias Müller    schedule 12.06.2015
comment
Auto mapper предназначен для сопоставления двух классов друг с другом. Используя Enumerable.First(), какое поведение вы ожидали от него при обратном отображении?   -  person Aron    schedule 12.06.2015
comment
Я ожидаю взять первую запись в свойстве Individuals-List в объекте секунд, имя которого - «Тест», и взять его идентификатор.   -  person Matthias Müller    schedule 15.06.2015
comment
Обратное отображение ... Плюс это требует, чтобы вы знали источник и поведение .First. Конечно, это легко сделать эвристически для человека ... Но вы попробуйте запрограммировать эвристику на компьютер!   -  person Aron    schedule 15.06.2015


Ответы (2)


У меня такое же исключение, и это может быть ошибка в AutoMapper, я не уверен, но у меня есть обходной путь в нерабочее время. Вот что у меня есть:

class MyDto
{
    public int? StatusId;
    public int? OtherStatusId;
}
class MyModel
{
    public int StatusId; 
}

// this should work normally
.ForMember(d => d.StatusId, c => c.MapFrom(f => f.Order.StatusId));
// this causes the exception above, but I don't know why, 
// maybe because I have some quite complex mapping
.ForMember(d => d.OtherStatusId, c => c.MapFrom(f => f.Other.StatusId));

// apply a cast on the source expression make the mapping smoothly
.ForMember(d => d.OtherStatusId, c => c.MapFrom(f => (int?)f.Other.StatusId));
person ltvan    schedule 15.06.2015
comment
Хм, спасибо, дружище, я тоже нашел другое решение. Я предполагаю, что это не ошибка как таковая, поскольку упаковка выполняется CLR, я обновлю свой вопрос, но ваш тоже наверняка является решением - person Matthias Müller; 17.06.2015

Я думаю, что у какой-то версии AutoMapper есть такая проблема. Я не уверен, что это все еще происходит в последней версии ???

Но главная проблема - это Nullable Expression, которую не так ясно решить. AutoMapper легче вернуть простое значение, например: c => c.Id, чем разрешить Nullable Expression, например c => c.Data.Path2.Data.Path2.Where(..).Id. Одним из способов решения этой проблемы может быть проверка на null (старый способ) ... лямбда-выражение дерева не может содержать нулевой распространяющий оператор

Кстати, Этот код плох, если вы пытаетесь использовать AutoMapper для сущностей БД .... Я предлагаю использовать ProjectTo и отправить параметр со списком IndividualIds. Дополнительная информация: http://docs.automapper.org/en/stable/Queryable-Extensions.html

person Jaider    schedule 17.01.2019