AspNetCoreOData
AspNetCoreOData copied to clipboard
IN Operator filter function stopped working after upgrading project to .net 8
Assemblies affected 8.2.3
Describe the bug "in" operator used in request filter on .net 8 application throws an exception.:
The LINQ expression '__TypedProperty_0
.Contains(MaterializeCollectionNavigation(
Navigation: Country.Translations,
subquery: DbSet<CountryTranslation>()
.Where(i => EF.Property<Guid?>(StructuralTypeShaperExpression:
Ewl.Platform.Geo.Storage.Entities.Country
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id") != null && object.Equals(
objA: (object)EF.Property<Guid?>(StructuralTypeShaperExpression:
Ewl.Platform.Geo.Storage.Entities.Country
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id"),
objB: (object)EF.Property<Guid?>(i, "CountryId"))))
.AsQueryable()
.Select(s => s.Name)
.ElementAt(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.
It occurs when in operator is used to query collection of children. Name property comes from Translation entity and is retrieved this way:
return (e) => new CountryListDto
{
Id = e.Id,
Name = e.Translations.First().Name,
}
Reproduce steps Request: https://.../countries?$filter=name in ('Angola')
Data Model
public class Country
{
public Guid Id { get; set; }
public ICollection<CountryTranslation> Translations { get; set; } = null!;
}
public class CountryTranslation
{
public Guid CountryId { get; set; }
public Country Country { get; set; } = null!;
public string Name { get; set; } = null!;
}
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="Dtos" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="CountryListDto">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.Guid" Nullable="false" />
<Property Name="name" Type="Edm.String" Nullable="false" MaxLength="64" />
</EntityType>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="countries" EntityType="Dtos.CountryListDto" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Request/Response https://.../countries?$filter=name in ('Angola')
Expected behavior List of countries is returned in response
Thank you @emjotnau for reporting the issue. Could you please confirm if it works in .NET7 and .NET6?
@emjotnau Please also confirm if you were using EF Core or EF6 before it stopped working. It'd help if you can share a repro for us to look at.
@gathogojr, Thanks for showing interest, I do confirm, it works on .net6 and .net7
@gathogojr Please take a look at simple project of API which the issue can be reproduced on: https://github.com/emjotnau/InOperatorTest
Request: https://localhost:7048/cr/countries?$filter=name in ('name2'),
Thank You
Could it be related to the breaking change of EF 8? "Contains in LINQ queries may stop working on older SQL Server versions" https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/breaking-changes#contains-in-linq-queries-may-stop-working-on-older-sql-server-versions
Could it be related to the breaking change of EF 8? "Contains in LINQ queries may stop working on older SQL Server versions" https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/breaking-changes#contains-in-linq-queries-may-stop-working-on-older-sql-server-versions
I have already checked it and in my reckoning that is not the case.
any news?