2

Basically I have a QueryExtender control of ASP.NET and First I need to Convert sql varchar value to TimeSpan of CSharp type then apply Linq OrderBy Clause on it, but get an error when execute.

Here is my code:

  protected void FilterProducts(object sender, CustomExpressionEventArgs e)
    {
      e.Query = (from p in e.Query.Cast<accounts>()
                  select p).OrderBy(p=> TimeSpan.Parse(p.TimeTo));
    }

ERROR: LINQ to Entities does not recognize the method 'System.TimeSpan Parse(System.String)' method, and this method cannot be translated into a store expression.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
Muhammad Adnan
  • 1,373
  • 1
  • 13
  • 20

2 Answers2

1

That is because TimeSpan.Parse is not available on the store, your query gets translated into SQL if you are using SQLServer, and that store doesn't have TimeSpan.Parse, one approach would be convert it to a list and then query again.

e.Query = (from p in e.Query.Cast<accounts>()
           select p).ToList().OrderBy(p=> TimeSpan.Parse(p.TimeTo));

But the above solution may cause some problem if ToList returns huge set of data.

Habib
  • 219,104
  • 29
  • 407
  • 436
  • You may see this thread as well http://stackoverflow.com/questions/4146300/linq-to-entityframework-datetime – Habib Aug 30 '12 at 08:55
  • This is a dangerous work-around, what happens if ToList() return a huge amount of data? – Muhammad Adnan Aug 30 '12 at 09:30
  • @MuhammadAdnanSaleem, didn't you see the last line on my answer ? I already said that. This is the problem with this approach. Its upto you – Habib Aug 30 '12 at 09:32
  • Thanks Habib, but is there any other workaround?? or wait for the next release of linq and entity framework? :) – Muhammad Adnan Aug 30 '12 at 09:36
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/16016/discussion-between-muhammad-adnan-saleem-and-habib) – Muhammad Adnan Aug 30 '12 at 09:39
  • @MuhammadAdnanSaleem, its not there in LINQ and I don't think it can be there in future versions, because its hard to implement, The best approach would be to use `Time` data type in SQL server rather than varchar – Habib Aug 30 '12 at 09:40
1

Without knowing all about the shape of your p.TimeTo data I think you can use the string value to order by, this way:

from p in e.Query.Cast<accounts>()
select p).OrderBy(p => p.TimeTo.Length).ThenBy(p => p.TimeTo)

This way, a value 1:00 will be sorted before 11:00.

EDIT

Take:

var s = new[] { "12:10", "8:00", "8:20",  "1:00", "1:02", "10:00", "11:10" };

And see the difference between

s.OrderBy (x => x);

and

s.OrderBy (x => x.Length).ThenBy (x => x);

Which is:

1:00
1:02
10:00
11:10
12:10
8:00
8:20

and

1:00
1:02
8:00
8:20
10:00
11:10
12:10

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291