I've been working with EF and EF Core for a long time, but there's something that has always given me problems, one way or the other, that is using methods inside queries, specially while mapping.
For example, right now I have this code
public IEnumerable<SelectObjDTO> SelectSearch()
{
return Context.Usuarios.IncludePerson().ToSelectObjDTO();
}
and in a different class
public static IQueryable<Users> IncludePerson(this IQueryable<Usuers> Query)
{
return Query.Include(x => x.Persons );
}
public static SelectObjDTO ToSelectObjDTO(this Persons POCO)
{
return new SelectObjDTO()
{
Id = POCO.Users.FirstOrDefault().Id,
FirstName= POCO.DocumentNumber+ " - " + POCO.FirstName + " " + POCO.LastName
};
}
public static IEnumerable<SelectObjDTO> ToSelectObjDTO(this IEnumerable<Persons> Query)
{
return Query.Select(POCO => POCO.ToSelectObjDTO());
}
The function IEnumerable<SelectObjDTO> ToSelectObjDTO(this IEnumerable<Persons> Query)
returns an error because the Users
is empty.
But in IEnumerable<SelectObjDTO> ToSelectObjDTO(this IEnumerable<Persons> Query)
the query does have something inside the Users
list.
This is this case, but before I've had other problems, for example an error from EF Core, which basically said that the context is running twice in the same query (I'm really sorry, can't remember exactly how it was), which was fixed by including whatever navigation property was being called.
Just in case, I'm using lazy loading proxies.
Thanks
ToSelectObjDTO
is a compiled function. You need to pass an Expression<Func<...>>
as the argument to Select()
. You can still compile it for other uses if you need to.
public static Expression<Func<Persons,SelectObjDTO>> SelectorFunc { get; } = POCO =>
new SelectObjDTO()
{
Id = POCO.Users.FirstOrDefault().Id,
FirstName= POCO.DocumentNumber+ " - " + POCO.FirstName + " " + POCO.LastName
};
public static Func<Persons,SelectObjDTO> Selector { get; } = SelectorFunc.Compile();
public static IQueryable<SelectObjDTO> ToSelectObjDTO(this IQueryable<Persons> Query)
=> Query.Select(SelectorFunc);