Hello. I have the problem with ProjectTo.
I have that Select map:
var posts = await appContext.Posts
.Select(x => new PostListReadModel()
{
IsAnonymous = x.IsAnonymous,
Publisher = !x.IsAnonymous ?
new PostPublisherReadModel()
{
Id = x.PublisherId,
Nick = x.Publisher.Nick,
PhoneNumber = x.Publisher.PhoneNumber,
Avatar = x.Publisher.Avatar
} :
null
})
.ToListAsync();
As you can see, I have a mapping condition for the Publisher property. Very simple condition.
It translates to sql like this:
SELECT p.IsAnonymous, NOT (p.IsAnonymous), p.PublisherId, u.Nick, u.PhoneNumber, i.Id, i.DateCreated, i.DateUpdated, i.FileName
FROM posts AS p
INNER JOIN users AS u ON p.PublisherId = u.Id
LEFT JOIN images AS i ON u.AvatarId = i.Id
And it works.
Now, I want to use ProjectTo. And I have a map configuration like this:
CreateMap<User, PostPublisherReadModel>();
CreateMap<Post, PostListReadModel>()
.ForMember(dest => dest.IsAnonymous, opt => opt.MapFrom(src => src.IsAnonymous))
.ForMember(dest => dest.Publisher, opt => opt.Condition(src => !src.IsAnonymous))
.ForAllOtherMembers(opt => opt.Ignore());
It translates to sql like this:
SELECT p.IsAnonymous, FALSE, i.Id, i.DateCreated, i.DateUpdated, i.FileName, u.Id, u.Nick, u.PhoneNumber
FROM posts AS p
INNER JOIN users AS u ON p.PublisherId = u.Id
LEFT JOIN images AS i ON u.AvatarId = i.Id
and it naturally doesn't work.
Is it an automapper error or am i doing something wrong?
I think this is better suited for StackOverflow.
I think this is better suited for StackOverflow.
I asked a question on SO:
https://stackoverflow.com/questions/60881865/simple-condition-with-projectto-doesnt-work
The very simple explanation is that the condition you have in your Select expression isn't the same as our condition. Our condition is roughly:
// precondition
if (typeMap.PreCondition(src), dest)
{
var srcValue = GetSrcValue(src);
var destValue = GetDestValue(dest);
if (typeMap.Condition(src, dest, srcValue, destValue)
{
dest.SetValue(srcValue);
}
}
Whereas you have a conditional operator ?:. That's a single expression. We do an if, you have an if/else.
As a rule of thumb, anything configuration method that accepts Expression<> is supported in LINQ, anything that accepts Func<> does not.
HOWEVER, it does seem that EF Core supports this. If we were to support it, we'd need a new overload, something like:
Condition(Expression<Func<TSource, bool>> condition, Expression<Func<TSource, TMember>> ifFalse)
HOWEVER, it does seem that EF Core supports this. If we were to support it, we'd need a new overload, something like:
So, should I wait in the future to fix the problem or not?
Based on the discussion in that issue, we do support what you're looking for. Just not with Condition. You need a MapFrom with that conditional operator in it. Condition is for "not mapping" not "have 2 paths for a map"
Based on the discussion in that issue, we do support what you're looking for. Just not with
Condition. You need aMapFromwith that conditional operator in it.Conditionis for "not mapping" not "have 2 paths for a map"
Before writing here, I tried this:
.ForMember(dest => dest.Publisher, opt => opt.MapFrom(src => !src.IsAnonymous ? src.Publisher : null)
and it failed
@bretbas then let's open a separate issue for that. MapFrom breaking is different than Condition.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.