I have entities that I map with automapper to domain models and return them from the service as Iqueryable. How can I use .Select or use automapper projectTo on them to map them to view models, because when I try I get thrown an error IAsyncEnumerable cannot be used for parameter of type IEnumerable on the navigation property inside the domain model?
class HomeDomainModel
{
public string Id { get; set; }
public ICollection<HumanDomainModel> Humans { get; set; }
}
class HumanDomainModel
{
public string Id { get; set; }
}
class HomaEntity
{
public string Id { get; set; }
public ICollection<HumanEntity> Humans { get; set; }
}
class HumanEntity
{
public string Id { get; set; }
}
// IQueryable<HomeEntity>
var homeEntities = homeEntities.GetAll();
// IQueryable<HomeDomainModel>
var homeDomainModels = humanEntity.ProjectTo<HomeDomainModel>();
// Here it throws the exception
var homeViewModel = homeDomainModels.Select(hdm => new HomeViewModel()
{
Id = hdm.Id,
HumansCount = hdm.Humans.Count()
}).ToArrayAsync();
If you want to map ICollection<HumanEntity> Humans { get; set; }
to HumansCount
, you could try code below:
Profile
public class ModelProfile: Profile
{
public ModelProfile()
{
CreateMap<HomaEntity, HomeViewModel>()
.ForMember(dest => dest.HumansCount, opt => opt.MapFrom(src => src.Humans.Count));
}
}
Use Case
var humanEntity = new List<HomaEntity> {
new HomaEntity{ Id = "T1", Humans = new List<HumanEntity>(){
new HumanEntity{ Id = "H1"},
} },
new HomaEntity{ Id = "TT1", Humans = new List<HumanEntity>(){
new HumanEntity{ Id = "HH1"},
new HumanEntity{ Id = "HH2"},
} },
new HomaEntity{ Id = "TT1", Humans = new List<HumanEntity>(){
new HumanEntity{ Id = "HHH1"},
new HumanEntity{ Id = "HHH2"},
new HumanEntity{ Id = "HHH3"}
} }
};
// Here it throws the exception
var homeViewModels = _mapper.Map<List<HomeViewModel>>(humanEntity);
Update
For EF Core, it has a concept of mixed client/database evaluation in LINQ queries. For your code, HumansCount = hdm.Humans.Count()
will run at client side and ToArrayAsync()
will run as server side or async.
Here are two options for you:
.ToArrayAsync()
to .ToArray()
.ToArrayAsync()
, you could try migrate your .net core 2.2 project to .net core 3.0 with using ef core 3.0 like version <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview8.19405.11" />