Хотя бы один объект должен реализовывать IComparable?

Модель:

return (from m in meterReadings
       group m by new { date = m.ReadDate } into g
       select new
       {
           ReadDate = g.Key.date.ToString("dd.MM.yyyy - HH:mm:ss"),
           T1 = from t1 in g
                where t1.Name == "T1"
                select t1.Value.ToString("0,0.000"),
           T2 = from t2 in g
                where t2.Name == "T2"
                select t2.Value.ToString("0,0.000"),
           T3 = from t3 in g
                where t3.Name == "T3"
                select t3.Value.ToString("0,0.000"),
           Total = from total in g
                where total.Name == "Toplam"
                select total.Value.ToString("0,0.000")
       }).AsQueryable<object>();

Запрос

var table = MeterReadingManager.GetMeterReadingsPivot(meterReadings, 1);
//No Error (in title)
rows = table.OrderBy("ReadDate","desc").Skip((pageIndex) * pageSize).Take(pageSize)
//Error  (in title)
rows = table.OrderBy("T1","desc").Skip((pageIndex) * pageSize).Take(pageSize)

Когда я заказываю по ReadDate, это работает. Но когда я пытаюсь заказать по другим полям, я получаю сообщение об ошибке: At least one object must implement IComparable

Почему я получаю эту ошибку? И как я могу это исправить?


person AliRıza Adıyahşi    schedule 28.11.2012    source источник


Ответы (2)


Если вы хотите отсортировать список элементов любого типа, тип должен реализовывать IComparable, чтобы алгоритм сортировки мог сравнивать элементы. T1 — это IQueryable, который не реализует IComparable. Я думаю, вы намеревались создать строковые значения для T1, T2 и T3. Если это так, вы должны добавить FirstOrDefault() к каждому оператору linq, создающему T1 и т. д.

Изменить

(После вашего комментария)

Я имею в виду это:

T1 = (from t1 in g
     where t1.Name == "T1"
     select t1.Value.ToString("0,0.000")).FirstOrDefault()

Теперь T1 является строкой и, следовательно, ее можно использовать при сортировке.

person Gert Arnold    schedule 28.11.2012
comment
Да. Ваше предложение работает. Но я не могу понять полностью. Особенно в последней фразе. Большое спасибо. - person AliRıza Adıyahşi; 28.11.2012

Вы можете попробовать ThenByDescending:

var rows = table
    .OrderByDescending(x => x.ReadDate).Skip((pageIndex) * pageSize).Take(pageSize)
    .ThenByDescending(x => x.T1).Skip((pageIndex) * pageSize).Take(pageSize);

ОБНОВЛЕНИЕ: вы можете использовать Reflection (немного медленнее) при упорядочении по одному полю:

var tableInfo = table.GetType().GetProperty("T1"); 
var sortedRow = table.OrderByDescending(x => tableInfo.GetValue(x, null)).Skip((pageIndex) * pageSize).Take(pageSize); 
person chridam    schedule 28.11.2012
comment
Я хочу заказать только по одному полю. Кроме того, с динамическим выражением linq. - person AliRıza Adıyahşi; 28.11.2012
comment
извините, но я хочу попробовать динамический запрос. Спасибо за ответ. - person AliRıza Adıyahşi; 28.11.2012