I have posted the issue to HC directly, but hoping to get some help from SO: https://github.com/ChilliCream/graphql-platform/issues/5827
I've added AutoMapper to our HC 12 + EF Core 7 project to complicate things a bit more. After lots of self reflection I finally got everything setup and projections / overfetching working by following this issue #4724 and a few others. Maybe my issue is related to some of the last minute warnings in the last comment?
My present issue is that sometimes filtering is not translated the way I'd expect and instead I get an Exception from EF.
I get this error when I filter on the disabled
property vs the id
or name
properties:
{
sites(where: { disabled: { eq: 1 } }) {
id
name
}
}
System.InvalidOperationException: 'The LINQ expression 'DbSet<InventSite>()
.Where(i => new LazySite{
Id = Convert.ToInt32(i.SiteId),
Name = i.Name
}
.Disabled == __p_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
However, if I filter another field it's OK
{
sites(where: { id: { eq: 1 } }) {
id
name
}
}
projects the proper SQL:
SELECT CONVERT(int, [i].[SiteID]) AS [Id], [i].[Name]
FROM [dbo].[InventSite] AS [i]
WHERE CONVERT(int, [i].[SiteID]) = @__p_0
Below is my project setup
Project Setup
My DTO
public class InventSite
{
public string DataAreaId { get; set; } = null!;
public string SiteId { get; set; } = null!;
public string? Dimension4 { get; set; }
public string? Name { get; set; }
public int Disabled { get; set; }
}
My exposed Graph entity
public class LazySite
{
public int Id { get; init; }
public int? AxSiteId { get; init; }
public string? Name { get; init; }
public int Disabled { get; init; }
}
AutoMapper profile
public MappingProfile()
{
CreateMap<InventSite, LazySite>()
.ForMember(d => d.Id, e => e.MapFrom(s => Convert.ToInt32(s.SiteId)))
.ForMember(d => d.AxSiteId, e => e.MapFrom(s => !string.IsNullOrWhiteSpace(s.Dimension4) ? (int?)Convert.ToInt32(s.Dimension4) : null))
//.ForMember(d => d.Disabled, e => e.MapFrom(s => s.Disabled))
.ForAllMembers(i => i.ExplicitExpansion());
}
Query
public class Query
{
[Authorize]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<LazySite> GetSites([Service] ISiteService siteService, IResolverContext resolverContext)
=> siteService.GetSites(resolverContext);
}
// ISiteService method:
public IQueryable<LazySite> GetSites(IResolverContext resolverContext)
=> _edrHelper.GetSites().ProjectTo<InventSite, LazySite>(resolverContext);
// IEdrHelper here
public IQueryable<InventSite> GetSites() =>
_context.InventSites.AsNoTracking();