Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using DateTime in Dynamic LINQ to Entities

I am using LINQ to Entities to retrieve item purchase dates as follows:

where EntityFunctions.TruncateTime(order.PurchaseDate) == myPurchaseDate.date

The key here is that the DB column contains the Date and Time so the time must be stripped for the compare. This code works fine.

Now, I want to do the same thing using dynamic LINQ to Entities. I am using dynamic.cs from the VS2010 code samples folder. When I code:

.where("EntityFunctions.TruncateTime(PurchaseDate) == @0", myPurchaseDate.date);

or any variant of same I get an error message. What do I have to code as the string value to make this work? (Since I can use .StartsWith or .Contains inside the string I am hoping there is some date function dynamic LINQ will recognize).

I know I can create the dynamic LINQ query to be a date range, conceptually:

PurchaseDate >= myPurchaseDate@midnight and PurchaseDate <= myPurchaseDate+23:59:59

In fact, maybe a date range is more efficient from a SQL Server perspective but I would like to know if something like TruncateTime or ToShortDate exists within Dynamic LINQ to Entities.

like image 396
user610342 Avatar asked Feb 09 '11 20:02

user610342


2 Answers

I recently started using dynamic linq for a project and also wanted to compare dates without the time component. Microsoft's dynamic linq C# sample code (Dynamic.cs) supports a fixed set of types, and EntityFunctions isn't one of them.

But with a little experimentation, I found that just adding EntityFunctions to the array of predefined types enables the use of TruncateTime and likely other EntityFunctions methods too.

Here's what the Dynamic.cs predefinedTypes array looks like in my project:

static readonly Type[] predefinedTypes = {
    typeof(Object),
    typeof(Boolean),
    typeof(Char),
    typeof(String),
    typeof(SByte),
    typeof(Byte),
    typeof(Int16),
    typeof(UInt16),
    typeof(Int32),
    typeof(UInt32),
    typeof(Int64),
    typeof(UInt64),
    typeof(Single),
    typeof(Double),
    typeof(Decimal),
    typeof(DateTime),
    typeof(TimeSpan),
    typeof(Guid),
    typeof(Math),
    typeof(Convert),
    typeof(System.Data.Objects.EntityFunctions)             // JimM
};

With this modified Dynamic.cs file, I'm able to create dynamic linq queries including expressions like the PurchaseDate example in your question.

like image 78
JimMat Avatar answered Nov 19 '22 18:11

JimMat


If your queries will often search by just the date aspect, another approach to consider, if available with your SQL Server database, would be to redundantly store a truncated version of the datetime column, in a date column type. See http://msdn.microsoft.com/en-us/library/bb630352.aspx).

All of your queries can then perform better because there are no conversions necessary, are less prone to developer error. And they're easier to query in plain old SQL as well.

Your EF queries would then query on the SQL Server date column

like image 21
Shan Plourde Avatar answered Nov 19 '22 19:11

Shan Plourde