any() functions generates untranslatable query
Open
@gathogojr is already working on this.
Since Apr 5, 2022.
bug
P2
- Dominant language
- C#
- Stars
- 505
- Forks
- 186
- PR merge metrics
- No merged PRs in 30d
Description
Assemblies affected
Microsoft.AspNetCore.OData 8.0.8
Describe the bug
I have the following data structure:
- Simple entity with a nav property on a collection (Employee)
- Second entity with nav property on a collection of first entities (Speciality) (many-to-many relationship)
- Bridge entity to bind them
When i do a query like this "https://localhost:7160/odata/Employees?$expand=Specialities&$filter=Specialities/any()"
I get an excection:
The LINQ expression 'DbSet<Employee>()
.Where(e => MaterializeCollectionNavigation(
Navigation: Employee.Specialities,
subquery: DbSet<EmployeeSpeciality>()
.Where(e0 => EF.Property<Guid?>(e, "Id") != null && object.Equals(
objA: (object)EF.Property<Guid?>(e, "Id"),
objB: (object)EF.Property<Guid?>(e0, "EmployeeId")))
.Join(
inner: DbSet<Speciality>(),
outerKeySelector: e0 => EF.Property<Guid?>(e0, "SpecialityId"),
innerKeySelector: s => EF.Property<Guid?>(s, "Id"),
resultSelector: (e0, s) => new TransparentIdentifier<EmployeeSpeciality, Speciality>(
Outer = e0,
Inner = s
))
.Select(ti => ti.Inner)) == null ? null : (bool?)DbSet<EmployeeSpeciality>()
.Where(e1 => EF.Property<Guid?>(e, "Id") != null && object.Equals(
objA: (object)EF.Property<Guid?>(e, "Id"),
objB: (object)EF.Property<Guid?>(e1, "EmployeeId")))
.Join(
inner: DbSet<Speciality>(),
outerKeySelector: e1 => EF.Property<Guid?>(e1, "SpecialityId"),
innerKeySelector: s0 => EF.Property<Guid?>(s0, "Id"),
resultSelector: (e1, s0) => new TransparentIdentifier<EmployeeSpeciality, Speciality>(
Outer = e1,
Inner = s0
))
.Any() == (bool?)True)' 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.
EntityFrameworkCore 6.0.3
Data Model
public class Employee
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public ICollection<Speciality> Specialities { get; set; } = new List<Speciality>();
public Guid? OrganizationId { get; set; }
public Organization? Organization { get; set; }
}
public class Speciality
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public ICollection<Employee> Employees { get; set; } = new List<Employee>();
}
internal class EmployeeSpeciality
{
public Guid EmployeeId { get; set; }
public Guid SpecialityId { get; set; }
}
EDM (CSDL) Model
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="GENERIS.Modules.Base.Entities" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Speciality">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" Nullable="false" />
<NavigationProperty Name="Employees" Type="Collection(GENERIS.Modules.Base.Entities.Employee)" />
</EntityType>
<EntityType Name="Employee">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" Nullable="false" />
<NavigationProperty Name="Specialities" Type="Collection(GENERIS.Modules.Base.Entities.Speciality)" />
<NavigationProperty Name="Organization" Type="GENERIS.Modules.Base.Entities.Organization" />
</EntityType>
<EntityType Name="Location">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" Nullable="false" />
<Property Name="ParentId" Type="Edm.Guid" />
<Property Name="Type" Type="GENERIS.Modules.Base.Entities.LocationType" Nullable="false" />
<NavigationProperty Name="Parent" Type="GENERIS.Modules.Base.Entities.Location" />
</EntityType>
<EntityType Name="Organization">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" Nullable="false" />
</EntityType>
<EntityType Name="Process">
<Key>
<PropertyRef Name="ProcessId" />
</Key>
<Property Name="ProcessId" Type="Edm.String" Nullable="false" />
<Property Name="CurrentStep" Type="Edm.String" Nullable="false" />
<Property Name="Input" Type="GENERIS.Modules.Base.Entities.Resource" Nullable="false" />
<Property Name="Output" Type="GENERIS.Modules.Base.Entities.Resource" Nullable="false" />
<Property Name="IsFinished" Type="Edm.Boolean" Nullable="false" />
</EntityType>
<ComplexType Name="Resource">
<Property Name="GetLink" Type="Edm.String" />
<Property Name="Type" Type="Edm.String" />
</ComplexType>
<EnumType Name="LocationType">
<Member Name="Country" Value="0" />
<Member Name="Region" Value="1" />
<Member Name="City" Value="2" />
<Member Name="Area" Value="3" />
<Member Name="Street" Value="4" />
<Member Name="Building" Value="5" />
<Member Name="Room" Value="6" />
<Member Name="Place" Value="7" />
</EnumType>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="Specialities" EntityType="GENERIS.Modules.Base.Entities.Speciality">
<NavigationPropertyBinding Path="Employees" Target="Employees" />
</EntitySet>
<EntitySet Name="Employees" EntityType="GENERIS.Modules.Base.Entities.Employee">
<NavigationPropertyBinding Path="Organization" Target="Organizations" />
<NavigationPropertyBinding Path="Specialities" Target="Specialities" />
</EntitySet>
<EntitySet Name="Locations" EntityType="GENERIS.Modules.Base.Entities.Location">
<NavigationPropertyBinding Path="Parent" Target="Locations" />
</EntitySet>
<EntitySet Name="Organizations" EntityType="GENERIS.Modules.Base.Entities.Organization" />
<EntitySet Name="Processes" EntityType="GENERIS.Modules.Base.Entities.Process" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Expected behavior
A LINQ expression generated by lib is translatable
Thats what is see in output
Microsoft.EntityFrameworkCore.Query: Debug: Compiling query expression:
DbSet<Employee>()
.Where($it => $it.Specialities == null ? null : (bool?)$it.Specialities
.Any() == (bool?)True)
.Select($it => new SelectAllAndExpand<Employee>{
Model = __TypedProperty_0,
Instance = $it,
UseInstanceForProperties = True,
Container = new NamedProperty<IEnumerable<SelectAll<Speciality>>>{
Name = "Specialities",
Value = $it == null ? null : $it.Specialities == null ? null : $it == null ? null : $it.Specialities
.Select($it => new SelectAll<Speciality>{
Model = __TypedProperty_1,
Instance = $it,
UseInstanceForProperties = True
}
)
}
}
)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.