0

From what I've read from this error, f.E. here: Why are some object properties UnaryExpression and others MemberExpression?

This happens, when an object is expected, but an value type is returned, so the CLR has to pack this, which is another (Unary)expression.

What really bothers me, the following AutoMapper-Mapping works without problems:

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

It only doesn't work, when the Mapping-Expression has another expression, which returns a Value Type:

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

I wrote this example just to show, what I'd like to do, so it might not be 100% appropriate? I just can't get behind, why the first Expression doesn't cause this exception, because in both cases an packing has to happen?

Edit

Itvan's answer works as well, the goal is just to remove the need for the wrapping. This works with something like this too:

m => m.MapFrom(f =>
    f.Individuals.Where(ms => ms.Individual.Name == name)
    .Select(i => i.Individual.Id).FirstOrDefault()
)
Community
  • 1
  • 1
Matthias Müller
  • 3,336
  • 3
  • 33
  • 65
  • Seems legit. The second isn't a property. AutoMapper is for mapping one object's properties to another class's properties. Also doing it by writing efficient IL. What you are doing is calling a LinqToObject method (which is clearly not a property). How is AutoMapper meant to reverse the mappings? – Aron Jun 11 '15 at 16:23
  • Well since it is working with reference types, I guess it is possible at all. The interestic part might be, where is he doing the packing and is it possible to tell him explicitely what type to take so he doesn't have to pack – Matthias Müller Jun 12 '15 at 11:23
  • No...how do you reverse the `first` method? – Aron Jun 12 '15 at 11:38
  • Sorry, I have no clue what you're asking for :| – Matthias Müller Jun 12 '15 at 14:43
  • Auto mapper is for mapping two class with each other. By using `Enumerable.First()` what behavior did you expect it do give you on the reverse mapping? – Aron Jun 12 '15 at 15:53
  • I expect to take the first Entry in the Individuals-List Property in the seconds object, where the name is 'Test' and take it's ID. – Matthias Müller Jun 15 '15 at 06:54
  • The reverse mapping...Plus that requires you to know the source and behavior of `.First`. Sure its easy to do heuristically for a human... But you try programming heuristics to a computer! – Aron Jun 15 '15 at 07:03

2 Answers2

2

I've just got the same exception and it may be a bug in the AutoMapper, I'm not sure, but I have a workaround after hours. This is what I have:

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));
ltvan
  • 308
  • 3
  • 7
  • Hm thanks buddy, I just found another solution as well. I guess it's not a bug per se, since the boxing is made by the CLR, I will update my question but your's is for sure a solution as well – Matthias Müller Jun 17 '15 at 06:50
0

I think some version of AutoMapper has this problem. I am not sure if this still happening on the latest version???

But the main issue it's the Nullable Expression that is not so clear to be resolved. It is easier for AutoMapper to return a simple value like: c => c.Id than resolve a Nullable Expression like c => c.Data.Path2.Data.Path2.Where(..).Id. One way to solve this could be check for null (old way)... an expression tree lambda may not contain a null propagating operator

By the way, This code is bad if you are trying to use AutoMapper for DB entities.... I will suggest to use ProjectTo and send a parameter with the list of IndividualIds. More info: http://docs.automapper.org/en/stable/Queryable-Extensions.html

Jaider
  • 14,268
  • 5
  • 75
  • 82