简体   繁体   中英

Comparing date with string Entity Framework

Lets assume that I have a SQL Server database and a table which looks like:

Id int NOT NULL,
Date date NOT NULL

I have corresponding entity framework model:

public class Bundle
{
    public int Id {get; set;}
    public DateTime Date {get; set;}
}

User can type a string that can be anything. I need to find all items where Date, or any part of date, contains string entered by user. So, basically, I need to perform query:

SELECT Id, Date
FROM Bundles
WHERE Date LIKE '%user_query_here%'

My first attempt was

query.Where(b => b.Date.ToShortDateString().Contains(filter.Date))

This throws a NotSupportedException, so I tried this:

query.Where(b => Convert.ToString(b.Date).Contains(filter.Date));

Please note, that filter.Date is string. Its not a DateTime structure.

This also throws an exception. So my question is how execute query written above?
PS: I can't perform filtering in memory, this table has many thousands of rows.

There's no simple way to convert a datetime to string with l2e, sadly.

You may use some SqlFunctions methods

SqlFunctions.DatePart

will return an int representing a part of the Date (year, month, day for example).

and

SqlFunctions.StringConvert

can help you to convert the int in a string (casting it to double first), which you can then concatenate.

Something like

.Where(b => (SqlFunctions.StringConvert((double)SqlFunctions.DatePart("y", b)) 
           + SqlFunctions.StringConvert((double)SqlFunctions.DatePart("m", b))
           //etc.
             ).Contains(filter.Date)

of course this is unreadable, and really not index-friendly.

A (much) easier and cleaner way, if you're working with sql server , would be to create and use a computed column .

You can create it like that (google to find how to do this properly if you use Code First and Migrations)

alter table add StringDate as convert(varchar, [Date], 112)//or another format, this will be yyyymmdd

If you use code first, you'll have to mark the property with attribute

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

Then you will be able to do

.Where(b => b.StringDate.Contains(filter.Date))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM