2013-01-14 61 views
2

從列表項,我有以下類別的產品清單。排序列表裏面

public class MonthlyConsumption : UserData 
{ 
    public string Unit { get; set; } 

    public List<DailyConsumption> DailyConsumptions { get; set; } 
} 

public class DailyConsumption 
{ 
    public DateTime Day { get; set; } 
    public double? Value { get; set; } 
} 

所以你可以看到,我有每個項目也有內部的天列表項的列表。

我的問題是我如何可以通過內部列表中的specyfic元素來排序我的主列表。

例如:我有類型MonthlyConsumption的列表。該列表中的每個元素都具有DailyConsumption類型的集合,並且此集合從今年1月起有第10天。我怎樣才能在1月1日之前訂購我的主要清單?

更新: 恐怕我把我的問題錯了的話,我真正想要做的是爲了我的類型MonthlyConsumption的列表,其中每個項目由特定的日值有自己的類型DailyConsumption 名單所以如果我的列表中的每個項目在10天內他內心的收集從1月1日至10日,我想價值一月1

更新到ordery我的主列表 我試圖

return monthlyConsumption.OrderBy(x => x.DailyConsumptions.Where(y => y.Day.Day == 1)) 
         .ToList(); 

但它給我至少一個對象必須實現IComparable

回答

1

如果我理解正確的,也許這樣的事情是你所追求的:

var targetDay = DateTime.Now; //set to Jan 1st 
var result = 
    monthylConsumptions.OrderBy(
     x => 
     x.DailyConsumptions.Where(y => y.Day.Date == targetDay.Date).Select(z => (!z.Value.HasValue ? 0 : z.Value.Value)).SingleOrDefault()); 

「targetDay」應設置爲1月1日,根據您的例子。

這將在您指定的那一天按Value進行升序排序,並且在特定每月沒有一個時考慮默認值。

編輯: 我剛剛測試了以下的單元測試,並把它傳遞,沒有顯示出您所描述的錯誤:

[TestFixture] 
public class LinqSortTest 
{ 
    public class MonthlyConsumption 
    { 
     public string Unit { get; set; } 

     public List<DailyConsumption> DailyConsumptions { get; set; } 
    } 

    public class DailyConsumption 
    { 
     public DateTime Day { get; set; } 
     public double? Value { get; set; } 
    } 

    [Test] 
    public void SomeTest() 
    { 
     var targetDay = new DateTime(2013, 1, 1); 
     var monthlyConsumptions = new List<MonthlyConsumption>(); 
     monthlyConsumptions.Add(new MonthlyConsumption 
      { 
       Unit = "first", 
       DailyConsumptions = new List<DailyConsumption> 
        { 
           new DailyConsumption { Day = new DateTime(2013, 1, 1), Value = 5 }, 
           new DailyConsumption { Day = new DateTime(2013, 1, 5), Value = 100 } 
        } 
      }); 
     monthlyConsumptions.Add(
      new MonthlyConsumption 
       { 
        Unit = "second", 
        DailyConsumptions = 
         new List<DailyConsumption> 
          { 
           new DailyConsumption { Day = new DateTime(2013, 1, 1), Value = 2 }, 
           new DailyConsumption { Day = new DateTime(2013, 1, 5), Value = 1 } 
          } 
       }); 

     var result = 
      monthlyConsumptions.OrderBy(
       x => 
       x.DailyConsumptions.Where(y => y.Day.Date == targetDay.Date).Select(
        z => (!z.Value.HasValue ? 0 : z.Value.Value)).SingleOrDefault()).ToList(); 

     Assert.AreEqual("second", result[0].Unit); 
    } 
} 

正如你所看到的,Assert證實,確實是第二個項目是首先放置,因爲「1st」的1月1日值低於「first」。

+0

好吧,我也這麼想,所以我甚至可以寫monthylConsumptions.OrderBy(x => x.DailyConsumptions.where(y => y.DayDay == 1)),但在我的和你的情況我有這個錯誤:At至少有一個對象必須實現IComparable – kosnkov

+0

我認爲這可能與價值是可空的有關

+0

我只是改變了一下。給那個一個鏡頭。 –

4

我還沒有測試過,但我相信你可以用Linq來做。假設「每月消費」爲List<MonthlyConsumption>

monthlyConsumptions.OrderBy(mc => mc.DailyConsumptions.Min(dc => dc.Day)); 

這將由他們最早DailyConsumption訂購您的MonthlyConsumption名單。

+0

恐怕我把我的問題寫錯了,請在我的帖子中編輯部分。 – kosnkov

+0

+1 - 謝謝你,jeremy,我有一個orderby的問題,然後是這樣一個簡單的屬性,然後你的'min'指向正確的方向。這是由於深層次的linq結構!但是,我現在將永遠知道如何解決它們 - 開玩笑! –

1

嘗試:

monthlyConsumptions 
    .SelectMany(mc => mc.DailyConsumptions) 
    .Where(dc = > dc.Day.Date.Day == 1 && dc.Day.Date.Month == 1) 
    .OrderBy(dc => dc.Value) 
    .Select(dc => dc.MonthlyConsumption); 

這將讓所有DailyConsumptions所有MonthlyConsumptions,那麼只有那些從一月的第一個過濾器,通過Value和,而不是從中獲得任何數據命令他們,它將返回是父實體MonthlyConsumption

所以你得到IQuerable<MonthlyConsumption>如你所願。

編輯:這將工作在LINQ實體,在你的情況下可能不是不幸的,除非你有DailyConsumption父母財產MonthlyConsumption