-
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
unable to groupby item.Date.Month #4581
Comments
@mikary can you confirm if this is fixed |
Ran the following sample against class Program
{
static void Main(string[] args)
{
using (var context = new MyContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var now = DateTimeOffset.UtcNow;
context.Add(new MyPoco { TimeStamp = now });
context.Add(new MyPoco { TimeStamp = now });
context.Add(new MyPoco { TimeStamp = now + TimeSpan.FromDays(90) });
context.SaveChanges();
}
using (var context = new MyContext())
{
var result = context.MyPocos.GroupBy(p => p.TimeStamp.Month).ToList();
foreach (var grouping in result)
{
Console.WriteLine("Key: {0}", grouping.Key);
Console.WriteLine("Values: {0}", string.Join(", ", grouping.Select(p => p.Id)));
}
}
}
}
public class MyPoco
{
public int Id { get; set; }
public DateTimeOffset TimeStamp { get; set; }
}
public class MyContext : DbContext
{
public DbSet<MyPoco> MyPocos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=GroupByDateTimeOffsetMonth;Integrated Security=True");
}
} Generated SQL SELECT [p].[Id], [p].[TimeStamp]
FROM [MyPocos] AS [p] |
Attempted to add test coverage to [ConditionalFact]
public virtual void GroupBy_DateTimeOffset_Property()
{
AssertQuery<Order>(os =>
os.Where(o => o.OrderDate.HasValue)
.GroupBy(o => o.OrderDate.Value.Month),
asserter: (l2oResults, efResults) =>
{
var efGroupings = efResults.Cast<IGrouping<int, Order>>().ToList();
foreach (IGrouping<int, Order> l2oGrouping in l2oResults)
{
var efGrouping = efGroupings.Single(efg => efg.Key == l2oGrouping.Key);
Assert.Equal(l2oGrouping.OrderBy(o => o.OrderID), efGrouping.OrderBy(o => o.OrderID));
}
},
entryCount: 830);
} This test passes with the SqlServer generated SQL: SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE [o].[OrderDate] IS NOT NULL
ORDER BY DATEPART(month, [o].[OrderDate]) Sqlite generated SQL: PRAGMA foreign_keys=OFF;
SELECT "o"."OrderID", "o"."CustomerID", "o"."EmployeeID", "o"."OrderDate"
FROM "Orders" AS "o"
WHERE "o"."OrderDate" IS NOT NULL The |
QueryPlan for Sqlite:
|
This also reproduces on SqlServer when there is a AssertQuery<Customer>(cs =>
cs.GroupBy(c => c.IsLondon),
asserter: (l2oResults, efResults) =>
{
var efGroupings = efResults.Cast<IGrouping<bool, Customer>>().ToList();
foreach (IGrouping<bool, Customer> l2oGrouping in l2oResults)
{
var efGrouping = efGroupings.Single(efg => efg.Key == l2oGrouping.Key);
Assert.Equal(l2oGrouping.OrderBy(o => o.CustomerID), efGrouping.OrderBy(o => o.CustomerID));
}
}); QueryPlan:
|
Our in-memory group by operator assumes that the entries are coming in the order of the grouping. Hence when we encounter different key we return groupings collected so far. This fails when the key for 2 rows are same but they is at least one row in between which has different key. |
I have a query to group records by one column "Date" of type DateTimeOffset.
I want to group via GroupBy(item=>item.Date.Month).
But it won't work!
Does ef7 support this kind of query?
Thanks in advance.
Details please see the kestrel logs:
C:\Users\XXXX\Documents\Visual Studio 2015\Projects\OfficeAutomation\src\WebApi>dnx web
Hosting environment: Production
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNet.Hosting.Internal.HostingEngine[1]
Request starting HTTP/1.1 GET http://localhost:5000/api/cartridges/costreports/2016
info: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[1]
Executing action method WebApi.Controllers.CartridgesController.GetAnnualCostReports with arguments (2016, Purchase, True) - ModelState is Valid'
info: Microsoft.AspNet.Hosting.Internal.HostingEngine[3]
Request finished in 0.1813ms 500
fail: Microsoft.AspNet.Server.Kestrel[13]
An unhandled exception was thrown by the application.
System.ArgumentException: Expression of type 'System.Func
2[Microsoft.Data.Entity.Query.EntityQueryModelVisitor+TransparentIdentifier
2[DataModels.CartridgeTransaction,Microsoft.Data.Entity.Storage.ValueBuffer],System.Int32]' cannot be used for parameter of type 'System.Func2[DataModels.CartridgeTransaction,System.Int32]' of method 'System.Collections.Generic.IAsyncEnumerable
1[System.Linq.IAsyncGrouping2[System.Int32,DataModels.CartridgeTransaction]] _GroupBy[CartridgeTransaction,Int32,CartridgeTransaction](System.Collections.Generic.IAsyncEnumerable
1[DataModels.CartridgeTransaction], System.Func2[DataModels.CartridgeTransaction,System.Int32], System.Func
2[DataModels.CartridgeTransaction,DataModels.CartridgeTransaction])'at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2)
at Microsoft.Data.Entity.Query.ResultOperatorHandler.HandleGroup(EntityQueryModelVisitor entityQueryModelVisitor, GroupResultOperator groupResultOperator, QueryModel queryModel)
at Microsoft.Data.Entity.Query.ResultOperatorHandler.HandleResultOperator(EntityQueryModelVisitor entityQueryModelVisitor, ResultOperatorBase resultOperator, QueryModel queryModel)
at Microsoft.Data.Entity.Query.Internal.RelationalResultOperatorHandler.HandleResultOperator(EntityQueryModelVisitor entityQueryModelVisitor, ResultOperatorBase resultOperator, QueryModel queryModel)
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, Int32 index)
at Microsoft.Data.Entity.Query.RelationalQueryModelVisitor.VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, Int32 index)
at Remotion.Linq.QueryModelVisitorBase.VisitResultOperators(ObservableCollection
1 resultOperators, QueryModel queryModel) at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.Data.Entity.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.Data.Entity.Query.Internal.SqlServerQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel) at Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func
1 compiler)at Microsoft.Data.Entity.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query)
at Microsoft.Data.Entity.Query.Internal.EntityQueryable
1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator() at System.Linq.AsyncEnumerable.Aggregate[TSource,TAccumulate,TResult](IAsyncEnumerable
1 source, TAccumulate seed, Func3 accumulator, Func
2 resultSelector, CancellationToken cancellationToken)at System.Linq.AsyncEnumerable.Aggregate[TSource,TAccumulate](IAsyncEnumerable
1 source, TAccumulate seed, Func
3 accumulator, CancellationToken cancellationToken)at System.Linq.AsyncEnumerable.ToDictionary[TSource,TKey,TElement](IAsyncEnumerable
1 source, Func
2 keySelector, Func2 elementSelector, IEqualityComparer
1 comparer, CancellationToken cancellationToken)at System.Linq.AsyncEnumerable.ToDictionary[TSource,TKey,TElement](IAsyncEnumerable
1 source, Func
2 keySelector, Func2 elementSelector, CancellationToken cancellationToken) at Microsoft.Data.Entity.EntityFrameworkQueryableExtensions.ToDictionaryAsync[TSource,TKey,TElement](IQueryable
1 source, Func2 keySelector, Func
2 elementSelector, CancellationToken cancellationToken)at WebApi.Controllers.CartridgesController.d__6.MoveNext() in C:\Users\kenny\Documents\Visual Studio 2015\Projects\OfficeAutomation\src\WebApi\Controllers\CartridgesController.cs:line 120
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor.d__8`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Routing.RouteCollection.d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Builder.RouterMiddleware.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.IISPlatformHandler.IISPlatformHandlerMiddleware.d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Hosting.Internal.HostingEngine.<>c__DisplayClass32_0.<b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Server.Kestrel.Http.Frame.d__79.MoveNext()
The text was updated successfully, but these errors were encountered: