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; }
}

如您所见,我有项目列表,其中每个项目还包含天数列表。

我的问题是如何通过内部列表中的特定元素对我的主列表进行排序。

示例:我有 MonthlyConsumption 类型的列表。该列表的每个元素都有 DailyConsumption 类型的集合,并且该集合从今年 1 月开始有 10 天。如何在 1 月 1 日之前订购我的主列表?

更新:恐怕我把我的问题用错误的话来表达,我真正想做的是订购我的 MonthlyConsumption 类型列表,其中每个项目在特定日期都有自己的 DailyConsumption 类型列表,所以如果我列表中的每个项目都有从 1 月 1 日到 10 日在他的内部收藏中的 10 天,我想在 1 月 1 日按价值订购我的主要清单。

更新 我试过

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

但它给了我至少一个对象必须实现IComparable

4

3 回答 3

4

我还没有测试过,但我相信你可以用 Linq 做到这一点。

假设“monthlyConsumptions”是List<MonthlyConsumption>.

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

MonthlyConsumption这将按它们最早的顺序排列您的 s 列表DailyConsumption

于 2013-01-14T04:28:18.167 回答
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确认确实将第二项放在第一位,因为“第二”的 1 月 1 日值低于“第一”。

于 2013-01-14T05:40:37.667 回答
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);

这将得到 all DailyConsumptionsfor all MonthlyConsumptions,然后仅过滤来自 1 月 1 日的那些,对它们进行排序,Value而不是从中获取任何数据,而是返回父实体,即MonthlyConsumption.

所以你得到IQuerable<MonthlyConsumption>你想要的命令。

编辑:这将在 LINQ to Entities 中起作用,在您的情况下可能不会很遗憾,除非您在DailyConsumption调用中具有父属性MonthlyConsumption

于 2013-01-14T10:08:46.990 回答