Reputation: 57
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.
Upvotes: 1
Views: 2521
Reputation: 60493
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))
Upvotes: 5