I have the following classes:
class Source {
public int Id { get; set; }
public string Name { get; set; }
public SourceItem Item { get; set; }
}
class SourceItem {
public Guid Id { get; set; }
public decimal Price { get; set; }
}
class Dest {
public int Id { get; set; }
public string Name { get; set; }
public DestItem Item { get; set; }
}
class DestItem{
public Guid Id { get; set; }
public decimal Price { get; set; }
}
And I built the following lambda expressions:
Expression<Func<Source, Dest>> projectionSource = source => new Dest{
Id = source.Id,
Name = source.Name
};
Expression<Func<SourceItem, DestItem>> projectionItem = item => new DestItem
{
Id = item.Id,
Price = item.Price
};
Expression<Func<Source, SourceItem>> sourceMember = source => source.Item;
Expression<Func<Dest, DestItem>> destMember = dest => dest.Item;
How do I add new element bindings to the list of element bindings of the original projection expression using the memberInitExpression expression from the projectionItem lambda expression? Lambda is needed at the output:
source => new Dest() // part of projectionSource expression
{
Id = source.Id,
Name = source.Name,
Item = new DestItem() // part of projectionItem expression
{
Id = source.Item.Id,
Price = source.Item.Price
}
}
I couldn't create a MemberAccess from the lambda destMember and projectionItem and add it to the Bindings List projectionSource.
You don't add a member to the bindings list, you build a new expression.
With following helper to replace parameters (if you have EF Core 3+ referenced you can use it's
ReplacingExpressionVisitorinstead):You can do something like the following:
Note that possibly it is worth investigating existing mapper libraries which support such stuff out of the box so you don't need to reinvent the wheel. For example popular AutoMapper "understands" "nested" mappings and supports building expressions to be consumed by LINQ providers - see the Queryable Extensions doc (search for
ProjectToandCreateProjectionsamples).