Dynamic LINQ DateTime Comparison String Building - Linq To Entities
Asked Answered
R

8

8

I'm using the dynamic LINQ library by Scott Guthrie together with Entity Framework and C#.

I have to build my where string into a variable based on several factors and then pass the string variable to the where clause. For some reason, this will work:

ContactList = ContactList.Where("DateAdded >= @0", DateTime.Parse("12/1/2012"));

But this will not work

string WhereClause = string.Format("DateAdded >= {0}", DateTime.Parse("12/1/2012"));
ContactList = ContactList.Where(WhereClause);

As mentioned, I need to use it in the version of passing the variable. Anyone know why the second doesn't work?

Thanks in advance!

Reputation answered 2/1, 2013 at 17:19 Comment(2)
SQL uses single quotes around DateTime fields - have you tried that? ... string.Format("DateAdded >= '{0}'", ...Thruster
Yes, tried that, same result. The solution I found was posted in my answer below. Thanks for the input.Reputation
R
4

It seems what I was trying to do is not possible with the current DynamicLINQ library. The reason it didn't work was well outlined below by Tilak.

My solution was to modify the DynamicLINQ library to allow the query to be written as a string and passed to the where clause for Date/Time datatypes. The modification was found here by Paul Hatcher: LINQ TO SQL, Dynamic query with DATE type fields

Reputation answered 3/1, 2013 at 19:52 Comment(0)
A
16

I was able to get it working with a slightly different string format using the information here.

Doing this worked fine for me:

ContactList.Where("DateAdded >= DateTime(2013, 06, 18)")

Note this does not work at all with DateTimeOffset columns.

Ammoniac answered 18/6, 2013 at 13:42 Comment(3)
Should be: DateTime(2013, 06, 18) ... Date isn't a supported function in Linq2Entities.Plumcot
And be careful not to name column DateTime because it will not work.Liston
just to add to @Makla's point - if any column is called DateTime, then no DateTime compression will work, no matter what are your other columns called..Cheju
R
4

It seems what I was trying to do is not possible with the current DynamicLINQ library. The reason it didn't work was well outlined below by Tilak.

My solution was to modify the DynamicLINQ library to allow the query to be written as a string and passed to the where clause for Date/Time datatypes. The modification was found here by Paul Hatcher: LINQ TO SQL, Dynamic query with DATE type fields

Reputation answered 3/1, 2013 at 19:52 Comment(0)
S
1

ObjectQuery.Where overload accepts 2 parameters.

  1. string predicate
  2. params ObjectParameter[] parameters

In your first example, Where builds the query (where clause) using ObjectParameter parameters (using Name, Type and Value of ObjectParameter)

In your second example, whatever is passed is treated as final where clause (no internal conversion based on datatype of passed parameters done).

Subteen answered 2/1, 2013 at 17:32 Comment(2)
Yes, I see where it is building the query when passing params, however, I can't seem to find a way to replicate what it is building. As I step through, it shows the final output as "Param_0 => (Param_0.DateAdded >= 12/1/2012 12:00:00 AM)". When I pass the string to be like that, it fails. Do you have any ideas on how I can get this to work by passing just the string variable without using params?Reputation
Explore System.Data.Entity.dll!ObjectQuery<T>.Where, EntitySqlQueryBuilder.Where and System.Data.Entity.dll!System.Data.Objects.Internal.EntitySqlQueryBuilder in your favorite dissasembler.Subteen
P
1

Based on Richard Rout's option, with a slight modification:

ContactList.Where("DateAdded >= DateTime(2013, 06, 18)")

This works in my Linq2Entities solution. Note the DateTime instead of Date. Hope this saves someone the headache this problem gave me.

Plumcot answered 7/3, 2014 at 15:39 Comment(0)
S
0

ContactList.Where probably puts quotes around non-numeric arguments (such as a DateTime). In your second string the date isn't quoted.

Stableman answered 2/1, 2013 at 17:20 Comment(1)
I've tried it with quotes, when you set string.Format("DateAdded >= \"{0}\"", DateTime.Parse("12/1/2012")) you end up with the error "Operator '>=' incompatible with operand types 'DateTime' and 'String'"Reputation
S
0

Had similar issue with dynamic linq core and ef 3.1 with sql server, solved it by explicitly setting up column type:

  1. Fluent way:

    modelBuilder.Entity<Contact>().Property(p => p.DateAdded).HasColumnType("datetime")
    
  2. Attribute way:

    public class Contact
    {
         [Column(TypeName = "datetime")]
         public DateTime DateAdded { get; set; }
    }
    

Usage:

ContactList = ContactList.Where("DateAdded == @0", "2021-03-25 02:29:00.000");

sql server datetime format: YYYY-MM-DD hh:mm:ss[.nnn]

Satiny answered 21/6, 2021 at 21:6 Comment(0)
G
0

I know this is an old question but if someone is still encountering this issue with ASP.Net Core, I was able to resolve it as follows.

Basically you have to add the Entity class(table column) with the Column attribute and specifying the TypeName. For the above question, it's as follows:

[Column(TypeName = "datetime")]
public DateTime DateAdded { get; set; }

That should fix the datatype conversion errors.

Source : https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/240

Gravely answered 13/10, 2021 at 14:20 Comment(0)
K
0

Kind of an old question, but in case this is helpful to anyone else, my issue was that it was taking my DateTime and making it a string. So the simple fix was to make it a date again. Something like:

var where = $"{propertyName} >= DateTime.Parse(\"{startDate}\") and {propertyName} <= DateTime.Parse(\"{endDate}\")";
query = query.Where(where);

It's a little more typing than adding the column attribute as The_Outsider said, but just another option.

Khano answered 16/11, 2021 at 16:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.