2015-11-18 6 views
0

У меня есть запрос linq, а внутри него - имя месяца. Я хочу, чтобы результаты отсортировались по месяцам (январь, февраль, март, ...).Сортировка по месяцам в linq и EF

В настоящее время у меня есть ниже, но это дает мне и ошибки:

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

var shockValues = (from s in ctx.Shocks 
           where s.ID == id 
           orderby DateTime.Parse(s.MonthName) 
           select new 
           { 
            val = s.MonthName + "=" + s.ShockValue 
           }); 
+1

почему не 'OrderBy s.MonthName' – Marshal

+0

если' MonthName' это «строка», вам нужно сделать что-то вроде «order by s.MonthName ==« Jan »? 1: s.MonthName == «Feb»? 2: ... '. – juharr

+1

Потому что это строка и не будет корректно упорядочиваться по месяцам – user441521

ответ

4

Вы имеете получил несколько вариантов. Вы можете использовать длинный список дополнительных операторов для отображения названия чисел

order by s.MonthName == "Jan" ? 1 : s.MonthName == "Feb" ? 2 : ... 

Вы могли бы создать таблицу в вашей БД, которая отображает имена для nummeric значений

var shockValues = (from s in ctx.Shocks 
        join o in MonthOrder on s.MonthName equals o.MonthName 
        where s.ID == id 
        orderby o.MonthNumber 
        select new 
        { 
         val = s.MonthName + "=" + s.ShockValue 
        }); 

или сделать заказ в памяти

var shockValues = (from s in ctx.Shocks 
        where s.ID == id 
        select new 
          { 
           s.MonthName, 
           s.ShockValue 
          }) 
        .AsEnumerable() 
        .OrderBy(s => DateTime.ParseExact(s.MonthName, "MMM", CultureInfo.InvariantCulture).Month) 
        .Select(s => new 
           { 
            val = s.MonthName + "=" + s.ShockValue 
           }); 
+0

Это ответ, хорошая работа. –

+0

В памяти один большой. Спасибо! – user441521

+0

@ user441521 Это хорошая идея, когда вы не ожидаете много шоков – esskar

0

Что-то, как это должно работать

var shockValues = ctx.Shocks.Where(s => s.ID == id).Select(x => new {x.MonthName, MonthNum = x.MonthName == "Jan" : 1 ? x.MonthName == "Feb" : 2 ? 0}).OrderBy(s => MonthNum).Select(s => new {val = s.MonthName + "=" + s.ShockValue}  
+0

Алфавитный порядок имен месяцев не совпадает с их порядком, как они происходят в течение года. – juharr

+0

Поскольку MonthName - это «Jan», Feb "и т. Д. Это не будет правильно упорядочено, потому что это строка. – user441521

+0

'DateTime.Parse' не будет работать с EF. Это проблема, с которой сталкивается ОП. – juharr

0

Try:

orderby Convert.ToDateTime(s.MonthName + " 1, " + DateTime.Now.Year.ToString()).Month 
+0

LINQ to Entities не распознает метод 'System.DateTime ToDateTime (System.String)', и этот метод не может быть переведен в выражение хранилища. – user441521

+0

Вы использовали «Convert.ToDatetTime» в отличие от «System.DateTime.ToDatetTime», правильно? –

+0

Это через EF, поэтому вы не можете использовать любую из этих функций напрямую. – user441521

0

Если вы не хотите, чтобы создать таблицу в базе данных, вы можете сделать как

var names = DateTimeFormatInfo.CurrentInfo.MonthNames 
      .Take(12).Select(s => new[] {s.Substring(0,3)}); 

А затем закажите отдельный список.

orderby names.IndexOf(s.MonthName) 
+0

Я не верю, что 'IndexOf' будет работать с EF. – juharr

+0

@juharr Но список имен не является списком EF его нормальным массивом строк. – Marshal

+0

EF все равно должен перевести это на SQL – juharr

0

Лучший способ и самый простой способ создать хранимую процедуру

Create procedure sortevents 
    as 
SELECT * 
     FROM [SAGMJ].[dbo].[Events] 
     ORDER BY CASE 
       WHEN MONTH([StartAt]) = MONTH(GETDATE()) 
        AND YEAR([StartAt]) = YEAR(GETDATE()) THEN 0 
        ELSE 1 
       END, [StartAt]; 

// Следующий вызов ваш зр

var v = (dc.sortevents()).ToList(); 
Смежные вопросы