2013-01-14 62 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