EFCore 7 reusable expression translation issues on collections

96 Views Asked by At

I have the following piece of projector:

public static Expression<Func<Order, OrderModel>> ProjectToOrderModel()
    {
        return order => new OrderModel
        {
            Uid = order.Uid,
            Table = ProjectToOrderTableModel(order.Table),
        };
    }

    public static TableModel ProjectToOrderTableModel(Table table) => new()
    {
        Id = table.Id,
        Name = table.Name
    };

Where Order is the EFCore entity and OrderModel is a POCO.

Whenever I do the following : db.Orders.Select(Mapper.ProjectToOrderModel())

The correct SQL is generated by using the projection fields and not querying the whole columns. This surprised me because ProjectToOrderTableModel is a function and not an expression.

However things get confusing when we get into lists. Rewriting the above snippet trying to include a nested collection

public static Expression<Func<Order, OrderModel>> ProjectToOrderModel()
    {
        return order => new OrderModel
        {
            Uid = order.Uid,
            Table = ProjectToOrderTableModel(order.Table),
            Items = order.OrderItems.AsQueryable().Select(MapToOrderItemsModel).ToList(),
        };
    }

    public static TableModel ProjectToOrderTableModel(Table table) => new()
    {
        Id = table.Id,
        Name = table.Name
    };

    public static OrderItemModel MapToOrderItemsModel(OrderItem i)
    {
         return new()
            {
                Uid = i.Uid,
                Name = i.Title,
                Price = i.Price
            };
    }

This fails because the Expression of type System.Func cannot be translated, which makes sense.

I cannot understand how it works for a singular model, but it cannot work on a collection... ? Is there any tracking bug, or is it a forbidden thing to do?!

P.S: I'm aware of the solution of implementing a public static Expression<Func<OrderItem, OrderItemModel>>, I just don't understand why the above doesn't work

0

There are 0 best solutions below