EF Core / .NET 6. Using an expression Select on entities

485 Views Asked by At

I'm trying to implement a Select with an Expression to keep the object as an IQueryable and selecting into a child navigation collection

Example Code:

public Expression<Func<Item, ItemModel>> MapToModel =>
        Ent => new ItemModel
        {
            Id = Ent.Id,
            Name = Ent.Name,
            SKU = Ent.SKU,
            Variations = Ent.Variations == null ? default : Ent.Variations.Select(this.VariationMapper),
        };

With the VariationMapper being the following:

public Expression<Func<ItemVariation, VariationModel>> VariationMapper =>
        Ent => new VariationModel()
        {
            Id = Ent.Id,
            Name = Ent.Name,
        };

I receive the following error however:

'ICollection' does not contain a definition for 'Select' and the best extension method overload 'Queryable.Select<ItemVariation, VariationModel>(IQueryable, Expression<Func<ItemVariation, VariationModel>>)' requires a receiver of type 'IQueryable'

I'm a bit perplexed as to how to resolve the issue. Or if this is even possible. That subproperty is type ICollection<T> as it's a navigation property.

2

There are 2 best solutions below

2
Guru Stron On

Try using the AsQueryable:

Variations = Ent.Variations == null 
    ? default 
    : Ent.Variations
         .AsQueryable()
         .Select(this.VariationMapper)
         .ToList()
0
Svyatoslav Danyliv On

You do not need to check for null for collections, EF Core will handle it. Also EF Core will not translate correctly your mapper. It needs expanding which is supplied by LINQKit.

public Expression<Func<Item, ItemModel>> MapToModel =>
        Ent => new ItemModel
        {
            Id = Ent.Id,
            Name = Ent.Name,
            SKU = Ent.SKU,
            Variations = Ent.Variations.Select(this.VariationMapper.Expand()),
        };

How to activate LINQKit, you can find in this answer, along with sample how to create reusable AsDto methods.