- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Difference between two date in minutes
Joined: 17-Jan-2012
Hi,
I would like to compute a time sheet for a user but I get the following error :
Aggregate function can't be applied as it's not possible to find a field to apply the aggregate on
First of all I'm using the latest version of LLBLGen (download today). .NET 3.5 and SQL Server Express 2008
Here is the tables involved in the query :
Employes
{
EmployesCode INT
FirstName NVARCHAR(150)
LastName NVARCHAR(150)
}
EmployesTimeSheet
{
EmployesCode INT
timeStart DATETIME NOT NULL
timeEnd DATETIME NULL
}
And now the LINQ query
var query = (from q in lmd.Employes
join tEmployesTimeSheet in lmd.EmployesTimeSheet on new { q.EmployesCode } equals new { tEmployesTimeSheet.EmployesCode } into groupJoinEmployesTimeSheet
from gEmployesTimeSheet in groupJoinEmployesTimeSheet.DefaultIfEmpty()
group new { q, tEmployesTimeSheet } by new
{
q.EmployesCode,
q.FirstName,
q.LastName
} into g
select new
{
g.Key.EmployesCode,
g.Key.FirstName,
g.Key.LastName,
EmployesTotalMinutesTimeSheet = g.Sum(p => p.gEmployesTimeSheet.timeEnd.Value - p.gEmployesTimeSheet.timeStart).TotalMinutes)
}).ToList();
Here is the stack trace for reference
SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryConstructionException was unhandled
Message="Aggregate function can't be applied as it's not possible to find a field to apply the aggregate on"
Source="SD.LLBLGen.Pro.LinqSupportClasses.NET35"
RuntimeBuild="11292011"
RuntimeVersion="3.1.0.0"
StackTrace:
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleAggregateExpressionReferencingGroupBy(AggregateExpression expressionToHandle, Expression handledSource, QueryExpression handledSourceAsQuery, Expression handledArgument, Expression handledElementSelector) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 492
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleAggregateExpression(AggregateExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 345
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 136
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 141
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleCtorOrMemberAssignmentParameter(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 4249
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleNewExpression(NewExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 2454
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 299
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 141
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleProjectionExpression(ProjectionExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 2622
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 201
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 141
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle, SelectExpression newInstance) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 818
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 796
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleSelectExpression(SelectExpression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 3154
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:line 207
at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:line 141
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProProviderBase.cs:line 158
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProProviderBase.cs:line 92
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProProviderBase.cs:line 697
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.Execute() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProQuery.cs:line 87
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v3.1\Frameworks\LLBLGen Pro\RuntimeLibraries\LinqSupportClasses\LLBLGenProQuery.cs:line 162
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at TestProject.Form1.Form1_Load(Object sender, EventArgs e) in D:\LLBLGenCTAQManager\TestProject\TestProject\TestProject\Form1.cs:line 408
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
InnerException:
Mmm. there are some things to note about your query:
-
It seems that you have an extra ")" that shouln't be there. Please double check that.
-
There is no a function mapping that would work on (someDate - someDate) or Substract. Then there is no function mapping that would return a TotalMinutes. Read here to know the supported built-in Linq function mappings. So you have to write your own function mapping. Example:
public class MyDBFunctions
{
public static int DateDiffInMinutes(DateTime dateStart, DateTime dateEnd)
{
return 0;
}
}
public class MyDBFunctionMappings : FunctionMappingStore
{
public MyDBFunctionMappings ()
: base()
{
this.Add(new FunctionMapping(typeof(MyDBFunctions), "DateDiffInMinutes", 2, "DATEDIFF(minute, {0}, {1})"));
}
}
.. then in your code (I reformatted it a little bit):
lmd.CustomFunctionMappings = new MyDBFunctionMappings();
var query =
(
from q in lmd.Employes
join tEmployesTimeSheet in lmd.EmployesTimeSheet on q.EmployesCode equals tEmployesTimeSheet.EmployesCode
into groupJoinEmployesTimeSheet
from gEmployesTimeSheet in groupJoinEmployesTimeSheet.DefaultIfEmpty()
group new { q, tEmployesTimeSheet } by new
{
q.EmployesCode,
q.FirstName,
q.LastName
} into g
select new
{
g.Key.EmployesCode,
g.Key.FirstName,
g.Key.LastName,
EmployesTotalMinutesTimeSheet =
g.Sum(p => MyDBFunctions.DateDiffInMinutes(p.gEmployesTimeSheet.timeEnd.Value, p.gEmployesTimeSheet.timeStart))
}).ToList();
Hope helpful
Joined: 17-Jan-2012
Thanks daelmo for your help
Now I see why the time operation was not working. The last extra ")" was a typo error, sorry.
I want to be as flexible as possible, so that my system can run on MS SQL Server, MySQL and MS Access for the worst.
If I write my own mapping function I loose this compatibility.
In conclusion, do you plan shortly supporting more timepsan and date operation ?
Best regards, Martin
erakis wrote:
I want to be as flexible as possible, so that my system can run on MS SQL Server, MySQL and MS Access for the worst.
If I write my own mapping function I loose this compatibility.
I understand what you mean. But you can overcome this. You can write this code in your DBGeneric project:
public class MyDBFunctions
{
public static int DateDiffInMinutes(DateTime dateStart, DateTime dateEnd)
{
return 0;
}
}
and this one in your DBSpecific project:
public class MyDBFunctionMappings : FunctionMappingStore
{
public MyDBFunctionMappings ()
: base()
{
this.Add(new FunctionMapping(typeof(MyDBFunctions), "DateDiffInMinutes", 2, "DATEDIFF(minute, {0}, {1})"));
}
}
Now you don't have that problem. If you change the target database, say from SQLServer to MySql then you need to generate another DBSpecific project, thus the MyDBFunctionMappings class as well, f.i.:
public class MyDBFunctionMappings : FunctionMappingStore
{
public MyDBFunctionMappings ()
: base()
{
this.Add(new FunctionMapping(typeof(MyDBFunctions), "DateDiffInMinutes", 2, "MINUTE(DATEDIFF({0}, {1}))"));
}
}
The DBGeneric code and your other projects remain the same, you just need to specialize the DBSpecifi project depending upon the target DB. You need to do this anyway if you have custom database functions.
erakis wrote:
In conclusion, do you plan shortly supporting more timepsan and date operation ?
I will see if there is any plans to increase the supported function mappings for LINQ2LLBL. What I guess is that there will be always some not supported functions you will have to map yourself.
For now there are no plans to extend the function mappings, as the ones we have are the most common ones and if you need a custom one, you can add it with a few lines with code which is located in your own project.