Skip to content
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 webapi core: sehexception when using $apply=aggregate #1413

Open
mysticdotnet opened this issue Apr 28, 2018 · 41 comments
Open

odata webapi core: sehexception when using $apply=aggregate #1413

mysticdotnet opened this issue Apr 28, 2018 · 41 comments
Assignees

Comments

@mysticdotnet
Copy link

mysticdotnet commented Apr 28, 2018

When i use $apply=aggregate with your sample (https://github.com/OData/WebApi/tree/master/samples/AspNetCoreODataSample.Web) it throw sehexception

Assemblies affected

*Microsoft.AspNetCore.OData with asp.net core

Reproduce steps

*I clone this project (https://github.com/OData/WebApi), i open this solution the odata core solution (WebApiOData.AspNetCore.sln)
and i run the sample project (https://github.com/OData/WebApi/tree/master/samples/AspNetCoreODataSample.Web)
and after i run this query: localhost:5912/odata/Movies?$apply=groupby((ReleaseDate)) *

Expected result

Show the result of the odata aggregate query

Actual result

sehexception

xuzhg added a commit to xuzhg/WebApi that referenced this issue May 1, 2018
@xuzhg
Copy link
Member

xuzhg commented May 1, 2018

@mysticdotnet

Thanks for tring our sample. I change the sample and verify that the sehexception is not from our codes. I do think it's from efcore.

Because, when I change to use the in-memory data, the same aggregate expression can work. for example:

image

But, when I switch to EFCore, it throws the sehexception.

@xuzhg xuzhg self-assigned this May 1, 2018
xuzhg added a commit to xuzhg/WebApi that referenced this issue May 1, 2018
xuzhg added a commit that referenced this issue May 1, 2018
@mysticdotnet
Copy link
Author

Thanks a lot for your help.
Should i submit a ticket to the ef core team with a reference to this issue ?

@xuzhg
Copy link
Member

xuzhg commented May 2, 2018

@mysticdotnet That's helpful. Let's follow up the input form EFCore. Thanks.

@xuzhg xuzhg reopened this May 2, 2018
@karelz
Copy link

karelz commented May 14, 2018

@xuzhg @ajcvickers can you please provide info about how to debug the underlying problem? -- see more details in https://github.com/dotnet/corefx/issues/29526#issuecomment-388932741
I can't always reproduce AV and it is not clear where things go wrong. If you have steps how to get to a failure point under debugger, I can help route it to the right place.

@ajcvickers
Copy link

@karelz I was unable even to repro the issue.

@xuzhg
Copy link
Member

xuzhg commented May 14, 2018

@karelz @ajcvickers
I think it's easy to repo using our sample project.

  1. Git clone:
git clone git@github.com:OData/WebApi.git
  1. VS2017 opens solution: https://github.com/OData/WebApi/blob/master/sln/WebApiOData.AspNetCore.sln

  2. Build and run: AspNetCoreODataSample.Web project

  3. Postman file request at: http://localhost:5913/efcore/Movies?$apply=groupby((ReleaseDate))

  4. Check the response, you will get the sehexception

Please let me know if it can't work at your side.

@karelz
Copy link

karelz commented May 14, 2018

@xuzhg that is exactly what I tried. Attached windbg to IISExpress - no exception. Even no sehexception in VS, just 502 as I posted in https://github.com/dotnet/corefx/issues/29526#issuecomment-388932741

@xuzhg
Copy link
Member

xuzhg commented May 14, 2018

Werid! It can't repo at my side now. @mysticdotnet Can you repro it?

@mysticdotnet
Copy link
Author

@xuzhg Sorry Sam, what do you mean by repo it ?

@mysticdotnet
Copy link
Author

@xuzhg I think the same issue 1221 is reported

@xuzhg
Copy link
Member

xuzhg commented May 15, 2018

@mysticdotnet Sorry. I mean to reproduce it.

@mysticdotnet
Copy link
Author

mysticdotnet commented May 16, 2018

@xuzhg the exception occurs every time
Repro:

  1. Clone / unzip https://github.com/OData/WebApi

  2. Open sln\WebApiOData.AspNetCore.sln

  3. Make samples\AspNetCoreODataSamples.Web project as StartUp project

  4. Run the project in Debug mode (F5) - Browser opens URL http://localhost:5912/efcore/Movies
    Browser will show:
    {"@odata.context":"http://localhost:5912/efcore/$metadata#Movies","value":[{"ID":1,"Title":"Conan","ReleaseDate":"2017-03-03T00:00:00-08:00","Genre":"Comedy","Price":1.99}]}

  5. Use URL in browser: http://localhost:5912/efcore/Movies?$apply=groupby((ReleaseDate))
    Result:

the application is in break mode

@xuzhg
Copy link
Member

xuzhg commented May 16, 2018

@karelz did you follow up @mysticdotnet 's step?

@karelz
Copy link

karelz commented May 16, 2018

@xuzhg I am able to repro problem (only in first F5 run in VS), but the exception is not coming from IISExpress process (nothing shows up in windbg) - see https://github.com/dotnet/corefx/issues/29526#issuecomment-388932741.
It is quite possible that the dialog is just a decoy / bug in VS itself, or it comes from other processes -- IMO we need to focus on what happens in IISExpress process (where the service runs I assume). I need area experts to find that out - once you tell me which native/managed exception to track down, I can help route it.

@mysticdotnet
Copy link
Author

mysticdotnet commented May 16, 2018

@karelz Repro without iisexpress:

  1. Open cmd prompt
  2. cd to debug folder: ...\WebApi\samples\AspNetCoreODataSample.Web\bin\Debug\netcoreapp2.0
  3. run this cmd: dotnet AspNetCoreODataSample.Web.dll
  4. launch Windbg
  5. Go to: File > Attach to Process
  6. The list of processes appear
  7. Select dotnet.exe process opened in step 3
  8. this output appear with some exceptions: output.txt
  9. Start debug in Windbg
  10. open browser with this link: localhost:5000/efcore/Movies?$apply=groupby((ReleaseDate))
  11. This output is appended with Access violation exception in it:

(1b40.2688): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
System_Private_CoreLib!System.Collections.Generic.Dictionary2+KeyCollection+Enumerator[System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken,System.__Canon]..ctor(System.Collections.Generic.Dictionary2<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken,System.__Canon>)$##600454E+0xf7562:
00007fff`695eb392 cd68 int 68h

@karelz
Copy link

karelz commented May 16, 2018

Can you please get a callstack from the AV? (k command in windbg, sxe eh or sxe av will stop on first-chance exceptions)

@mysticdotnet
Copy link
Author

@karelz With k command i have this output now: output.txt

@mysticdotnet
Copy link
Author

@karelz @xuzhg I do the same test with asp.net core 2.1 release, unfortunately, i have the same error. Maybe it's a .net core clr issue !

@mysticdotnet
Copy link
Author

@karelz @xuzhg I have more information now:
1-I edit AspNetCoreODataSample.Web.csproj, i add this PropertyGroup:
<PropertyGroup> <RuntimeIdentifier>win10-x86</RuntimeIdentifier> </PropertyGroup>
2-After that i run the app in Debug Mode (F5)
3-open browser with this link: localhost:5000/efcore/Movies?$apply=groupby((ReleaseDate))
4-Line 80 of DynamicTypeWrapper.cs throw this exception:

readmemory

5-I change the line 80 like this:

line80

6- Re run the app, i get another exception here:

serialize

@karelz
Copy link

karelz commented May 31, 2018

The stack trace above (#1413 (comment)) is missing some symbols :(
@xuzhg can you please help to get the right callstack form the repro for further routing?

@mysticdotnet
Copy link
Author

@karelz With .symfix[+] [LocalSymbolCache] cmd, i have this output
output.txt and this stack stack.txt

@mysticdotnet
Copy link
Author

@karelz @xuzhg did you see the Jan analysis about this issue ?

@mysticdotnet
Copy link
Author

@xuzhg Did you expect a fix for this issue in the beta phase ?

@xuzhg
Copy link
Member

xuzhg commented Jun 15, 2018

@mysticdotnet Sorry for later response. What do you mean beta? That's in OData side or EFCore side?

@mysticdotnet
Copy link
Author

@xuzhg I mean OData.

@xuzhg
Copy link
Member

xuzhg commented Jun 21, 2018

@mysticdotnet Sorry, I am a little bit confusing.

  1. Did you figure out the root cause?

  2. If yes, where comes the root cause? in OData side, or EFCore side?

  3. If that's OData problem, would you please share us what your found?

  4. If that's EFCore problem, it's better to fix , but OData itself doesn't depend on it.

@mysticdotnet
Copy link
Author

@xuzhg I don't have more information about the root cause. Sorry for that and thank you very much

@smitpatel
Copy link

I investigated based on data provided and information given by .NET team and we may have possible cause of the issue here.

Ref: thread on EF Core repo which has more details (dotnet/efcore#12733)

Particularly posting last outcome from corefx team

From @jkotas

The crash is caused by invalid IL generated via Reflection.Emit.

Method Name:  DynamicClass.lambda_method(System.Runtime.CompilerServices.Closure, AspNetCoreODataSample.Web.Models.Movie)

IL_0000: newobj 6000002 Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper..ctor()
IL_0005: dup 
IL_0006: newobj 6000003 Microsoft.AspNet.OData.Query.Expressions.AggregationPropertyContainer+LastInChain..ctor()
IL_000b: dup 
IL_000c: ldstr 70000004 "ReleaseDate"
IL_0011: callvirt 6000005 
IL_0016: dup 
IL_0017: ldarg.1 
// This returns System.DateTimeOffset
IL_0018: callvirt 6000006 AspNetCoreODataSample.Web.Models.Movie.get_ReleaseDate()
// This passes it to method that object reference - bad type mismatch!!!!
IL_001d: callvirt 6000007 Microsoft.AspNet.OData.Query.Expressions.PropertyContainer+NamedProperty`1[[System.__Canon, System.Private.CoreLib]].set_Value(System.__Canon) IL_0022: callvirt 6000008 Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper.set_GroupByContainer(Microsoft.AspNet.OData.Query.Expressions.AggregationPropertyContainer)
IL_0027: ret 

The method with invalid IL is created at this callstack:

system_private_corelib!System.Reflection.Emit.DynamicMethod.GetMethodDescriptor()+0x10a
system_private_corelib!System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type, System.Object)+0x2a
DynamicClass.lambda_method(System.Runtime.CompilerServices.Closure, Microsoft.EntityFrameworkCore.Query.QueryContext)+0x1a2
microsoft_entityframeworkcore!Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[[System.Int32, System.Private.CoreLib]](System.Linq.Expressions.Expression)+0x7456ac12
microsoft_entityframeworkcore!Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[[System.Int32, System.Private.CoreLib]](System.Linq.Expressions.Expression)+0x74562e78
remotion_linq!Remotion.Linq.QueryableBase`1[[System.__Canon, System.Private.CoreLib]].System.Collections.IEnumerable.GetEnumerator()+0x21
newtonsoft_json!Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(Newtonsoft.Json.JsonWriter, System.Collections.IEnumerable, Newtonsoft.Json.Serialization.JsonArrayContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)+0xe5
newtonsoft_json!Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)+0x18d
newtonsoft_json!Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(Newtonsoft.Json.JsonWriter, System.Object, System.Type)+0xf1
newtonsoft_json!Newtonsoft.Json.JsonSerializer.SerializeInternal(Newtonsoft.Json.JsonWriter, System.Object, System.Type)+0x468
newtonsoft_json!Newtonsoft.Json.JsonSerializer.Serialize(Newtonsoft.Json.JsonWriter, System.Object)+0x14
microsoft_aspnetcore_mvc_formatters_json!Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter.WriteObject(System.IO.TextWriter, System.Object)+0x53
microsoft_aspnetcore_mvc_formatters_json!Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter+<WriteResponseBodyAsync>d__11.MoveNext()+0xf6
system_private_corelib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[System.__Canon, System.Private.CoreLib]](System.__Canon ByRef)+0xffffffff`ab1048d9
microsoft_aspnetcore_mvc_formatters_json!Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter.WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext, System.Text.Encoding)+0x65
microsoft_aspnetcore_mvc_core!Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter.WriteAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext)+0x160

As @divega mentioned on that thread, EF Core does not use Reflection.Emit so bad IL is not result of something in EF Core.

I hand-crafted the query being created by OData for particular request. There is slight mismatch in what compiler generates vs what OData generated.
Hand-written query (had to make some internal class public)

                var query = _context.Movies.AsNoTracking()
                    .GroupBy(it => new GroupByWrapper
                    {
                        GroupByContainer = new AggregationPropertyContainer.LastInChain
                        {
                            Name = "ReleaseDate",
                            Value = it.ReleaseDate
                        }
                    })
                .Select(it => new AggregationWrapper
                {
                    GroupByContainer = it.Key.GroupByContainer
                }).ToList();

IQueryable.Expression output for both the queries.

// Hand-written version
.Call System.Linq.Queryable.Select(
    .Call System.Linq.Queryable.GroupBy(
        .Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking(.Constant<Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[AspNetCoreODataSample.Web.Models.Movie]>(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[AspNetCoreODataSample.Web.Models.Movie]))
        ,
        '(.Lambda #Lambda1<System.Func`2[AspNetCoreODataSample.Web.Models.Movie,Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper]>))
    ,
    '(.Lambda #Lambda2<System.Func`2[System.Linq.IGrouping`2[Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper,AspNetCoreODataSample.Web.Models.Movie],Microsoft.AspNet.OData.Query.Expressions.AggregationWrapper]>))

.Lambda #Lambda1<System.Func`2[AspNetCoreODataSample.Web.Models.Movie,Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper]>(AspNetCoreODataSample.Web.Models.Movie $it)
{
    .New Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper(){
        GroupByContainer = .New Microsoft.AspNet.OData.Query.Expressions.AggregationPropertyContainer+LastInChain(){
            Name = "ReleaseDate",
            Value = (System.Object)$it.ReleaseDate
        }
    }
}

.Lambda #Lambda2<System.Func`2[System.Linq.IGrouping`2[Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper,AspNetCoreODataSample.Web.Models.Movie],Microsoft.AspNet.OData.Query.Expressions.AggregationWrapper]>(System.Linq.IGrouping`2[Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper,AspNetCoreODataSample.Web.Models.Movie] $it)
{
    .New Microsoft.AspNet.OData.Query.Expressions.AggregationWrapper(){
        GroupByContainer = ($it.Key).GroupByContainer
    }
}


// OData Version
.Call System.Linq.Queryable.Select(
    .Call System.Linq.Queryable.GroupBy(
        .Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking(.Constant<Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[AspNetCoreODataSample.Web.Models.Movie]>(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[AspNetCoreODataSample.Web.Models.Movie]))
        ,
        '(.Lambda #Lambda1<System.Func`2[AspNetCoreODataSample.Web.Models.Movie,Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper]>))
    ,
    '(.Lambda #Lambda2<System.Func`2[System.Linq.IGrouping`2[Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper,AspNetCoreODataSample.Web.Models.Movie],Microsoft.AspNet.OData.Query.Expressions.AggregationWrapper]>))

.Lambda #Lambda1<System.Func`2[AspNetCoreODataSample.Web.Models.Movie,Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper]>(AspNetCoreODataSample.Web.Models.Movie $$it)
{
    .New Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper(){
        GroupByContainer = .New Microsoft.AspNet.OData.Query.Expressions.AggregationPropertyContainer+LastInChain(){
            Name = "ReleaseDate",
            Value = $$it.ReleaseDate
        }
    }
}

.Lambda #Lambda2<System.Func`2[System.Linq.IGrouping`2[Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper,AspNetCoreODataSample.Web.Models.Movie],Microsoft.AspNet.OData.Query.Expressions.AggregationWrapper]>(System.Linq.IGrouping`2[Microsoft.AspNet.OData.Query.Expressions.GroupByWrapper,AspNetCoreODataSample.Web.Models.Movie] $$it)
{
    .New Microsoft.AspNet.OData.Query.Expressions.AggregationWrapper(){
        GroupByContainer = ($$it.Key).GroupByContainer
    }
}

Output of query model printer in EF Core (Query Model is generated by parsing the Expression tree using Remotion.Linq)

//Hand-written version
dbug: Microsoft.EntityFrameworkCore.Query[10101]
      Compiling query model:
      'from IGrouping<GroupByWrapper, Movie> e in
          (from Movie <generated>_1 in DbSet<Movie>
          select [<generated>_1])
          .AsNoTracking()
          .GroupBy(new GroupByWrapper() {GroupByContainer = new LastInChain() {Name = "ReleaseDate", Value = Convert([<generated>_1].ReleaseDate, Object)}}, [<generated>_1])
      select new AggregationWrapper{ GroupByContainer = [e].Key.GroupByContainer }
      '
dbug: Microsoft.EntityFrameworkCore.Query[10104]
      Optimized query model:
      'from IGrouping<GroupByWrapper, Movie> e in
          (from Movie <generated>_1 in DbSet<Movie>
          select [<generated>_1]).GroupBy(new GroupByWrapper() {GroupByContainer = new LastInChain() {Name = "ReleaseDate", Value = Convert([<generated>_1].ReleaseDate, Object)}}, [<generated>_1])
      select new AggregationWrapper{ GroupByContainer = [e].Key.GroupByContainer }
      '
dbug: Microsoft.EntityFrameworkCore.Query[10107]
      (QueryContext queryContext) => IEnumerable<AggregationWrapper> _InterceptExceptions(
          source: IEnumerable<AggregationWrapper> _Select(
              source: IEnumerable<IGrouping<GroupByWrapper, Movie>> _GroupBy(
                  source: IEnumerable<Movie> EntityQuery(
                      queryContext: queryContext,
                      entityType: EntityType: Movie,
                      key: Key: Movie.ID PK,
                      materializer: (IEntityType entityType | ValueBuffer valueBuffer) =>
                      {
                          instance = new Movie()
                          instance.<ID>k__BackingField = int TryReadValue(valueBuffer, 0, Movie.ID)
                          instance.<Genre>k__BackingField = Genre TryReadValue(valueBuffer, 1, Movie.Genre)
                          instance.<Price>k__BackingField = decimal TryReadValue(valueBuffer, 2, Movie.Price)
                          instance.<ReleaseDate>k__BackingField = DateTimeOffset TryReadValue(valueBuffer, 3, Movie.ReleaseDate)
                          instance.<Title>k__BackingField = string TryReadValue(valueBuffer, 4, Movie.Title)
                          return instance
                      }
                      ,
                      queryStateManager: False),
                  keySelector: (Movie <generated>_1) => new GroupByWrapper{ GroupByContainer = new LastInChain{
                          Name = "ReleaseDate",
                          Value = (object)<generated>_1.ReleaseDate
                      }
                       }
                  ,
                  elementSelector: (Movie <generated>_1) => <generated>_1),
              selector: (IGrouping<GroupByWrapper, Movie> e) => new AggregationWrapper{ GroupByContainer = e.Key.GroupByContainer }
          ),
          contextType: AspNetCoreODataSample.Web.Models.MovieContext,
          logger: DiagnosticsLogger<Query>,
          queryContext: queryContext)

//OData version
dbug: Microsoft.EntityFrameworkCore.Query[10101]
      Compiling query model:
      'from IGrouping<GroupByWrapper, Movie> $it in
          (from Movie <generated>_1 in DbSet<Movie>
          select [<generated>_1])
          .AsNoTracking()
          .GroupBy(new GroupByWrapper() {GroupByContainer = new LastInChain() {Name = "ReleaseDate", Value = [<generated>_1].ReleaseDate}}, [<generated>_1])
      select new AggregationWrapper{ GroupByContainer = [$it].Key.GroupByContainer }
      '
dbug: Microsoft.EntityFrameworkCore.Query[10104]
      Optimized query model:
      'from IGrouping<GroupByWrapper, Movie> $it in
          (from Movie <generated>_1 in DbSet<Movie>
          select [<generated>_1]).GroupBy(new GroupByWrapper() {GroupByContainer = new LastInChain() {Name = "ReleaseDate", Value = [<generated>_1].ReleaseDate}}, [<generated>_1])
      select new AggregationWrapper{ GroupByContainer = [$it].Key.GroupByContainer }
      '
dbug: Microsoft.EntityFrameworkCore.Query[10107]
      (QueryContext queryContext) => IEnumerable<AggregationWrapper> _InterceptExceptions(
          source: IEnumerable<AggregationWrapper> _Select(
              source: IEnumerable<IGrouping<GroupByWrapper, Movie>> _GroupBy(
                  source: IEnumerable<Movie> EntityQuery(
                      queryContext: queryContext,
                      entityType: EntityType: Movie,
                      key: Key: Movie.ID PK,
                      materializer: (IEntityType entityType | ValueBuffer valueBuffer) =>
                      {
                          instance = new Movie()
                          instance.<ID>k__BackingField = int TryReadValue(valueBuffer, 0, Movie.ID)
                          instance.<Genre>k__BackingField = Genre TryReadValue(valueBuffer, 1, Movie.Genre)
                          instance.<Price>k__BackingField = decimal TryReadValue(valueBuffer, 2, Movie.Price)
                          instance.<ReleaseDate>k__BackingField = DateTimeOffset TryReadValue(valueBuffer, 3, Movie.ReleaseDate)
                          instance.<Title>k__BackingField = string TryReadValue(valueBuffer, 4, Movie.Title)
                          return instance
                      }
                      ,
                      queryStateManager: False),
                  keySelector: (Movie <generated>_1) => new GroupByWrapper{ GroupByContainer = new LastInChain{
                          Name = "ReleaseDate",
                          Value = <generated>_1.ReleaseDate
                      }
                       }
                  ,
                  elementSelector: (Movie <generated>_1) => <generated>_1),
              selector: (IGrouping<GroupByWrapper, Movie> $it) => new AggregationWrapper{ GroupByContainer = $it.Key.GroupByContainer }
          ),
          contextType: AspNetCoreODataSample.Web.Models.MovieContext,
          logger: DiagnosticsLogger<Query>,
          queryContext: queryContext)

Based on ExpressionTree & QueryModel output, the difference is in GroupByWrapper creation, where assigning ReleaseDate to Value property has Convert node since release date is DateTime and Value is of type object. Further, according to @jkotas 's post there is bad type mismatch happening inside IL after getting value of ReleaseDate and assigning it to Value Property. Based on missing Convert node in OData query, it is likely that that is generating invalid IL.

Compiler introduce this Convert node automatically when you hand write the query. I am not sure whether it is needed or why OData is not introducing it. And what are its implication in IL. Perhaps coreFx team can provide more information on that. If current Expression Tree generated by OData is invalid (given compiler generates slightly different then) OData team can fix it. Or if the ExpressionTree is valid then it should not be generating error in IL when evaluating in memory. (perhaps corefx issue).

Since EF Core is working correctly for compiler generated Expression Tree, I will be closing this issue on EF Core side.

@ikemtz
Copy link

ikemtz commented Sep 4, 2018

Any update on the fix for this issue from the OData side?

@techniq
Copy link

techniq commented Sep 4, 2018

See also: #1154 (comment)

There is also #1221, which is a duplicate of this issue (been open longer, but still a duplicate)

@vinils
Copy link

vinils commented Jan 12, 2019

I´m struggling with data problem too since I can´t make a groupby.
Would be nice to have a work-around or an ETA
I tracked this bug to a year ago and since groupby(aggregate) its a kind of basic query resource wouldn't this bug be a p1 blocking?
Regards,

@jannikbuschke
Copy link

Im also facing this issue

@SenyaMur
Copy link

SenyaMur commented Mar 1, 2019

I found solution. Just change one method in AggregationBinder class

        private Expression WrapConvert(Expression expression)
        {
            return Expression.Convert(expression, typeof(object));
            // return this._linqToObjectMode
            //     ? Expression.Convert(expression, typeof(object))
            //     : expression;
        }

Now always use convert for property

@esbenbach
Copy link

Any updates on this?

@kenanilgun
Copy link

I found solution. Just change one method in AggregationBinder class

        private Expression WrapConvert(Expression expression)
        {
            return Expression.Convert(expression, typeof(object));
            // return this._linqToObjectMode
            //     ? Expression.Convert(expression, typeof(object))
            //     : expression;
        }

Now always use convert for property

Hi SenyaMur, Can you give example to here please.

@SenyaMur
Copy link

I found solution. Just change one method in AggregationBinder class

        private Expression WrapConvert(Expression expression)
        {
            return Expression.Convert(expression, typeof(object));
            // return this._linqToObjectMode
            //     ? Expression.Convert(expression, typeof(object))
            //     : expression;
        }

Now always use convert for property

Hi SenyaMur, Can you give example to here please.

What example you need? Request url or fix the bug?
If you want to fix the bug, then just clone the repository, change code as i writed and build it.

@kosinsky
Copy link
Contributor

Issue should be fixed by: #1728 Could you try nightly build to check that fix works for you?

@SenyaMur
Copy link

It's worked on build 7.1.1-Nightly201907241245.
When it will be in nuget?

@SenyaMur
Copy link

SenyaMur commented Aug 8, 2019

It's worked on 7.2.0. Thank you!

@SenyaMur
Copy link

Not work on 7.3.0 :(

@Bilal-El-Mursi
Copy link

Bilal-El-Mursi commented Jun 22, 2020

Did you try to use services.AddControllers().AddNewtonsoftJson();? It seems to solve some of the issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests