我有以下课程的项目列表:
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 按特定日期的值列表,所以如果每个我的清单中的项目从1月1日到10日在他的内部集合中有10天,我想按照jan 1中的值排序我的主列表。
更新 我试过了
return monthlyConsumption.OrderBy(x => x.DailyConsumptions.Where(y => y.Day.Day == 1))
.ToList();
但它给了我至少一个对象必须实现IComparable
。
答案 0 :(得分:4)
我没有测试过,但我相信你可以用Linq做到。
假设“monthlyConsumptions”是List<MonthlyConsumption>
。
monthlyConsumptions.OrderBy(mc => mc.DailyConsumptions.Min(dc => dc.Day));
这将最早MonthlyConsumption
订购DailyConsumption
的列表。
答案 1 :(得分: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日。
这将按指定日期的值按升序排序,并在每月特定月份中考虑默认值。
修改强> 我刚刚测试了下面的单元测试,它通过了,没有显示你所描述的错误:
[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
确认第二项确实放在第一位,因为“第二”的Jan 1值低于“第一”。
答案 2 :(得分: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
,然后仅过滤1月1日的那些,按Value
排序,而不是从中获取任何数据,它返回父实体这是MonthlyConsumption
。
所以你按照自己的意愿订购IQuerable<MonthlyConsumption>
。
编辑:这将在LINQ to Entities中运行,在您的情况下可能并非遗憾,除非您在DailyConsumption
中拥有名为MonthlyConsumption
的父属性。