Skip to content

Using projection with nested expressions. #34866

@boppercr

Description

@boppercr

Is there a way to still use projections with nested expression?

Here's some additionnal information. I have an entity that has one or many DTOs of it. Theses DTOs contain other DTOs from other entities, say a Blog has a Category which in turn has a SubCategory. I created a Mapper that works really well when there's only a few layers that looks like this :

public static class BlogMapper
{
    public static Expression<Func<Blog, BlogDTO>> ToBlogDTO = x =>
        new Blog
        {
            //Other properties
            Category = CategoryMapper.ToCategoryDTO.Compile.Invoke(x.Category);
        }
}

public static class CategoryMapper
{
    public static Expression<Func<Category, CategoryDTO>> ToCategoryDTO = x =>
        new Category
        {
            //Other properties
            SubCategory = SubCategoryMapper.ToSubCategoryDTO.Compile.Invoke(x.SubCategory);
        }
}

public static class SubCategoryMapper
{
    public static Expression<Func<SubCategory, SubCategoryDTO>> ToSubCategoryDTO = x =>
        new SubCategory
        {
            //Other properties
        }
}

Then I can use it like the following :

_context.Blogs.Select(BlogMapper.ToBlogDTO).ToList();

The issue arises because the query created by EF Core doesn't contain the SubCategory table and therefor its value is null when trying to map.

It feels like the projection stops at a certain level and I'm not sure I understand why.

The main thing is that I wouldn't want the BlogMapper to take care of the Category and SubCategory mappings since I know I'll already have dedicated mappers for this exact purpose. I'm not gonna lie, I feel like I'm either missing something or that it "doesn't make sense" to go at it like that but I can't seem to find the alternative.

I've tried an approach with simple constructors and they won't work with projection as well. I even tried to create an ExpressionVisitor to "flatten" the resulting expression somehow, but it didn't work as well. I can provide the code if need be, but like I said, I feel like I'm gone too far in the wrong direction.

Include provider and version information

EF Core version: 8.0.10
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions