-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OData Linq Expression not be translated issue using automapper #27460
Comments
Updated: If i enabled 'HandleNullPropagation = false', it works fine. @maumar Why does "nullable" can't work? Or I misunderstand something? var settings = new ODataQuerySettings { HandleNullPropagation = HandleNullPropagationOption.False };
var queried = ODataQuery.ApplyTo(baseQuery, settings) as IQueryable<dynamic>; Here's the debug view (This is working linq expression). .Call System.Linq.Queryable.Select(
.Call System.Linq.Queryable.Select(
.Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ThenInclude(
.Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Include(
.Extension<Microsoft.EntityFrameworkCore.Query.QueryRootExpression>,
'(.Lambda #Lambda1<System.Func`2[TimeSheet.API.Models.Entity.Consulente,System.Collections.Generic.ICollection`1[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa]]>))
,
'(.Lambda #Lambda2<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa,TimeSheet.API.Models.Entity.Commessa]>))
,
'(.Lambda #Lambda3<System.Func`2[TimeSheet.API.Models.Entity.Consulente,TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto]>))
,
'(.Lambda #Lambda11<System.Func`2[TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto,Microsoft.AspNetCore.OData.Query.Wrapper.SelectAllAndExpand`1[TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto]]>))
.Lambda #Lambda1<System.Func`2[TimeSheet.API.Models.Entity.Consulente,System.Collections.Generic.ICollection`1[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa]]>(TimeSheet.API.Models.Entity.Consulente $b)
{
$b.N_Consulente_Commessa
}
.Lambda #Lambda2<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa,TimeSheet.API.Models.Entity.Commessa]>(TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa $x)
{
$x.Commessa
}
.Lambda #Lambda3<System.Func`2[TimeSheet.API.Models.Entity.Consulente,TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto]>(TimeSheet.API.Models.Entity.Consulente $dtoConsulente)
{
.New TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto(){
AddedDate = (System.Nullable`1[System.DateTime])$dtoConsulente.AddedDate,
CodiceFiscale = $dtoConsulente.CodiceFiscale,
Email = $dtoConsulente.Email,
Id = $dtoConsulente.Id,
ModifiedDate = $dtoConsulente.ModifiedDate,
N_CaricamentiTimeSheet = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
$dtoConsulente.N_CaricamentiTimeSheet,
.Lambda #Lambda4<System.Func`2[TimeSheet.API.Models.Entity.Time_Sheet,TimeSheet.API.Models.Dto.Api.TimeSheetF.TimeSheetDto]>)),
N_Consulente_Commessa = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
$dtoConsulente.N_Consulente_Commessa,
.Lambda #Lambda8<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]>)
),
Name = $dtoConsulente.FirstName,
NumeroMatricola = $dtoConsulente.NumeroMatricola,
Surname = $dtoConsulente.LastName
}
}
.Lambda #Lambda4<System.Func`2[TimeSheet.API.Models.Entity.Time_Sheet,TimeSheet.API.Models.Dto.Api.TimeSheetF.TimeSheetDto]>(TimeSheet.API.Models.Entity.Time_Sheet $dtoTime_Sheet)
{
.New TimeSheet.API.Models.Dto.Api.TimeSheetF.TimeSheetDto(){
AddedDate = (System.Nullable`1[System.DateTime])$dtoTime_Sheet.AddedDate,
Anno = $dtoTime_Sheet.Anno,
ConsulenteId = $dtoTime_Sheet.ConsulenteId,
FileExcel = $dtoTime_Sheet.ExcelPath,
Id = $dtoTime_Sheet.Id,
Mese = $dtoTime_Sheet.Mese,
ModifiedDate = $dtoTime_Sheet.ModifiedDate,
RowTimeSheetDetail = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
$dtoTime_Sheet.RowTimeSheetDetail,
.Lambda #Lambda5<System.Func`2[TimeSheet.API.Models.Entity.RowTimeSheet,TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto]>)
)
}
}
.Lambda #Lambda5<System.Func`2[TimeSheet.API.Models.Entity.RowTimeSheet,TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto]>(TimeSheet.API.Models.Entity.RowTimeSheet $dtoRowTimeSheet)
{
.New TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto(){
AddedDate = (System.Nullable`1[System.DateTime])$dtoRowTimeSheet.AddedDate,
Giorno = $dtoRowTimeSheet.Giorno,
Id = $dtoRowTimeSheet.Id,
ModifiedDate = $dtoRowTimeSheet.ModifiedDate,
N_Commessa_RowTimeSheet = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
$dtoRowTimeSheet.N_Commessa_RowTimeSheet,
.Lambda #Lambda6<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Commessa_RowTimeSheet,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Commessa_RowTimeSheetDto]>)
),
OreFerie_Permessi = $dtoRowTimeSheet.OreFerie_Permessi,
TimeSheetCaricamentoId = $dtoRowTimeSheet.TimeSheetCaricamentoId
}
}
.Lambda #Lambda6<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Commessa_RowTimeSheet,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Commessa_RowTimeSheetDto]>(TimeSheet.API.Models.Entity.ThirdTableRelationship.Commessa_RowTimeSheet $dtoCommessa_RowTimeSheet)
{
.New TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Commessa_RowTimeSheetDto(){
Commessa = .If ($dtoCommessa_RowTimeSheet.Commessa == null) {
null
} .Else {
.New TimeSheet.API.Models.Dto.Api.CommessaF.CommessaDto(){
AddedDate = (System.Nullable`1[System.DateTime])($dtoCommessa_RowTimeSheet.Commessa).AddedDate,
CommessaCompletata = ($dtoCommessa_RowTimeSheet.Commessa).CommessaCompletata,
Id = ($dtoCommessa_RowTimeSheet.Commessa).Id,
ModifiedDate = ($dtoCommessa_RowTimeSheet.Commessa).ModifiedDate,
N_Consulente_Commessa = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
($dtoCommessa_RowTimeSheet.Commessa).N_Consulente_Commessa,
.Lambda #Lambda7<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]>)
),
Name = ($dtoCommessa_RowTimeSheet.Commessa).Name
}
},
CommessaId = $dtoCommessa_RowTimeSheet.CommessaId,
OreOrdinarie = $dtoCommessa_RowTimeSheet.OreOrdinarie,
OreStraordinarie = $dtoCommessa_RowTimeSheet.OreStraordinarie,
RowTimeSheetId = $dtoCommessa_RowTimeSheet.RowTimeSheetId
}
}
.Lambda #Lambda7<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]>(TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa $dtoConsulente_Commessa)
{
.New TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto(){
AddedDate = (System.Nullable`1[System.DateTime])$dtoConsulente_Commessa.AddedDate,
CommessaId = $dtoConsulente_Commessa.CommessaId,
ConsulenteId = $dtoConsulente_Commessa.ConsulenteId,
Id = $dtoConsulente_Commessa.Id,
ModifiedDate = $dtoConsulente_Commessa.ModifiedDate
}
}
.Lambda #Lambda8<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]>(TimeSheet.API.Models.Entity.ThirdTableRelationship.Consulente_Commessa $dtoConsulente_Commessa)
{
.New TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto(){
AddedDate = (System.Nullable`1[System.DateTime])$dtoConsulente_Commessa.AddedDate,
Commessa = .If ($dtoConsulente_Commessa.Commessa == null) {
null
} .Else {
.New TimeSheet.API.Models.Dto.Api.CommessaF.CommessaDto(){
AddedDate = (System.Nullable`1[System.DateTime])($dtoConsulente_Commessa.Commessa).AddedDate,
CommessaCompletata = ($dtoConsulente_Commessa.Commessa).CommessaCompletata,
Id = ($dtoConsulente_Commessa.Commessa).Id,
ModifiedDate = ($dtoConsulente_Commessa.Commessa).ModifiedDate,
N_Commessa_RowTimesheet = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
($dtoConsulente_Commessa.Commessa).N_Commessa_RowTimesheet,
.Lambda #Lambda9<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Commessa_RowTimeSheet,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Commessa_RowTimeSheetDto]>)
),
Name = ($dtoConsulente_Commessa.Commessa).Name
}
},
CommessaId = $dtoConsulente_Commessa.CommessaId,
ConsulenteId = $dtoConsulente_Commessa.ConsulenteId,
Id = $dtoConsulente_Commessa.Id,
ModifiedDate = $dtoConsulente_Commessa.ModifiedDate
}
}
.Lambda #Lambda9<System.Func`2[TimeSheet.API.Models.Entity.ThirdTableRelationship.Commessa_RowTimeSheet,TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Commessa_RowTimeSheetDto]>(TimeSheet.API.Models.Entity.ThirdTableRelationship.Commessa_RowTimeSheet $dtoCommessa_RowTimeSheet)
{
.New TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Commessa_RowTimeSheetDto(){
CommessaId = $dtoCommessa_RowTimeSheet.CommessaId,
OreOrdinarie = $dtoCommessa_RowTimeSheet.OreOrdinarie,
OreStraordinarie = $dtoCommessa_RowTimeSheet.OreStraordinarie,
RowTimeSheet = .If ($dtoCommessa_RowTimeSheet.RowTimeSheet == null) {
null
} .Else {
.New TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto(){
AddedDate = (System.Nullable`1[System.DateTime])($dtoCommessa_RowTimeSheet.RowTimeSheet).AddedDate,
Giorno = ($dtoCommessa_RowTimeSheet.RowTimeSheet).Giorno,
Id = ($dtoCommessa_RowTimeSheet.RowTimeSheet).Id,
ModifiedDate = ($dtoCommessa_RowTimeSheet.RowTimeSheet).ModifiedDate,
OreFerie_Permessi = ($dtoCommessa_RowTimeSheet.RowTimeSheet).OreFerie_Permessi,
TimeSheetCaricamento = .If (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento == null) {
null
} .Else {
.New TimeSheet.API.Models.Dto.Api.TimeSheetF.TimeSheetDto(){
AddedDate = (System.Nullable`1[System.DateTime])(($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).AddedDate,
Anno = (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).Anno,
ConsulenteId = (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).ConsulenteId,
FileExcel = (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).ExcelPath,
Id = (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).Id,
Mese = (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).Mese,
ModifiedDate = (($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).ModifiedDate,
RowTimeSheetDetail = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select(
(($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamento).RowTimeSheetDetail,
.Lambda #Lambda10<System.Func`2[TimeSheet.API.Models.Entity.RowTimeSheet,TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto]>))
}
},
TimeSheetCaricamentoId = ($dtoCommessa_RowTimeSheet.RowTimeSheet).TimeSheetCaricamentoId
}
},
RowTimeSheetId = $dtoCommessa_RowTimeSheet.RowTimeSheetId
}
}
.Lambda #Lambda10<System.Func`2[TimeSheet.API.Models.Entity.RowTimeSheet,TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto]>(TimeSheet.API.Models.Entity.RowTimeSheet $dtoRowTimeSheet)
{
.New TimeSheet.API.Models.Dto.Api.RowTimeSheetF.RowTimeSheetDto(){
AddedDate = (System.Nullable`1[System.DateTime])$dtoRowTimeSheet.AddedDate,
Giorno = $dtoRowTimeSheet.Giorno,
Id = $dtoRowTimeSheet.Id,
ModifiedDate = $dtoRowTimeSheet.ModifiedDate,
OreFerie_Permessi = $dtoRowTimeSheet.OreFerie_Permessi,
TimeSheetCaricamentoId = $dtoRowTimeSheet.TimeSheetCaricamentoId
}
}
.Lambda #Lambda11<System.Func`2[TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto,Microsoft.AspNetCore.OData.Query.Wrapper.SelectAllAndExpand`1[TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto]]>(TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto $$it)
{
.New Microsoft.AspNetCore.OData.Query.Wrapper.SelectAllAndExpand`1[TimeSheet.API.Models.Dto.Api.ConsulenteF.ConsulenteDto](){
Model = .Constant<Microsoft.AspNetCore.OData.Query.Container.LinqParameterContainer+TypedLinqParameterContainer`1[Microsoft.OData.Edm.IEdmModel]>(Microsoft.AspNetCore.OData.Query.Container.LinqParameterContainer+TypedLinqParameterContainer`1[Microsoft.OData.Edm.IEdmModel]).TypedProperty,
Instance = $$it,
UseInstanceForProperties = True,
Container = .New Microsoft.AspNetCore.OData.Query.Container.NamedProperty`1[System.Collections.Generic.IEnumerable`1[Microsoft.AspNetCore.OData.Query.Wrapper.SelectAll`1[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]]]()
{
Name = "N_Consulente_Commessa",
Value = .Call System.Linq.Enumerable.Select(
.Call System.Linq.Enumerable.Where(
$$it.N_Consulente_Commessa,
.Lambda #Lambda12<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,System.Boolean]>),
.Lambda #Lambda13<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,Microsoft.AspNetCore.OData.Query.Wrapper.SelectAll`1[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]]>)
}
}
}
.Lambda #Lambda12<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,System.Boolean]>(TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto $$it)
{
$$it.CommessaId < .Constant<Microsoft.AspNetCore.OData.Query.Container.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int32]>(Microsoft.AspNetCore.OData.Query.Container.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int32]).TypedProperty
}
.Lambda #Lambda13<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,Microsoft.AspNetCore.OData.Query.Wrapper.SelectAll`1[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]]>(TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto $$it)
{
.New Microsoft.AspNetCore.OData.Query.Wrapper.SelectAll`1[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]()
{
Model = .Constant<Microsoft.AspNetCore.OData.Query.Container.LinqParameterContainer+TypedLinqParameterContainer`1[Microsoft.OData.Edm.IEdmModel]>(Microsoft.AspNetCore.OData.Query.Container.LinqParameterContainer+TypedLinqParameterContainer`1[Microsoft.OData.Edm.IEdmModel]).TypedProperty,
Instance = $$it,
UseInstanceForProperties = True
}
} |
with null propagation: Value = .If (.If ($$it == null) {
null
} .Else {
.If ($$it.N_Consulente_Commessa == null) {
null
} .Else {
.Call System.Linq.Enumerable.Where(
$$it.N_Consulente_Commessa,
.Lambda #Lambda12<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,System.Boolean]>)
}
} == null) {
null
} .Else {
.Call System.Linq.Enumerable.Select(
.If ($$it == null) {
null
} .Else {
.If ($$it.N_Consulente_Commessa == null) {
null
} .Else {
.Call System.Linq.Enumerable.Where(
$$it.N_Consulente_Commessa,
.Lambda #Lambda12<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,System.Boolean]>)
}
},
.Lambda #Lambda13<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,Microsoft.AspNetCore.OData.Query.Wrapper.SelectAll`1[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]]>)
} without null propagation: Value = .Call System.Linq.Enumerable.Select(
.Call System.Linq.Enumerable.Where(
$$it.N_Consulente_Commessa,
.Lambda #Lambda12<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,System.Boolean]>),
.Lambda #Lambda13<System.Func`2[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto,Microsoft.AspNetCore.OData.Query.Wrapper.SelectAll`1[TimeSheet.API.Models.Dto.Api.ThirdTableRelationship.Consulente_CommessaDto]]>)
} OData is adding these extra terms for null propagation which complicates the query to a point that we can't translate it (at the moment). We should try to recognize/simplify these patterns, although they are largely unnecessary - EF Core is pretty good with handling null propagation itself |
@maumar Thanks for your input. We have below comments for the Null propagation setting for a perid of time, So, it seems it's still a problem in EF Core 6.0? |
@xuzhg in EFCore 5 and 6 we have improved a number of translations involving projections and composing on top of them. It's possible that some scenarios that OData produces are still broken - let me add some tests in out OData suite and see how things are now. Basically, before EF Core 3 we used to do a lot of client evaluations, if we didn't know how to translate something, we would fall back to in memory and then stitch the results together. In newer versions, we don't allow that anymore, apart from projection, but we got much better at translating more patterns - now we try to translate everything and if we can't, we throw. here is an example of translation(s) that have been enabled recently: |
File a bug
One of our customers want to query data using
It works fine, we can get the following:
However, if we put a $filter in the URI like:
It throws exception as:
Here's the screenshot:
Here's the call-stack:
Here's the Linq expression "C#" notation:
Here's Linq Expression debug view:
Welcome any hint. If you need more detail, please contact 'Sam Xu' at "[email protected]. Thanks.
The text was updated successfully, but these errors were encountered: