C# 从列表中的列表中按项目排序

C# 从列表中的列表中按项目排序,c#,.net,linq,sorting,C#,.net,Linq,Sorting,我有以下类别的项目清单: public class MonthlyConsumption : UserData { public string Unit { get; set; } public List<DailyConsumption> DailyConsumptions { get; set; } } public class DailyConsumption { public DateTime Day { get; set; } publi

我有以下类别的项目清单:

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

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

我还没有测试过它,但是我相信你可以用Linq来实现它

假设“monthlyConsumptions”是一个
列表


这将按最早的
日消费量
对您的
月消费量
列表进行排序

如果我理解正确的话,也许这就是你想要的:

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日

这将按你指定的日期按升序排序,并在特定月份中没有一个时考虑默认值。< /P> 编辑: 我刚刚测试了以下单元测试,它通过了,没有显示您描述的错误:

[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);
    }
}
[TestFixture]
公共类LinqSortTest
{
公课每月消费
{
公共字符串单元{get;set;}
公共列表DailyConsumptions{get;set;}
}
公共类日常消费
{
公共日期时间日{get;set;}
公共双精度值{get;set;}
}
[测试]
公共测试()
{
var targetDay=新日期时间(2013,1,1);
var monthlyconsumpions=新列表();
monthlyConsumptions.添加(新的MonthlyConsumption
{
Unit=“第一”,
DailyConsumptions=新列表
{
新的DailyConsumption{Day=newDateTime(2013,1,1),Value=5},
新的DailyConsumption{Day=new DateTime(2013,1,5),Value=100}
}
});
每月消费。添加(
新月份消费
{
Unit=“秒”,
日常消费=
新名单
{
新的DailyConsumption{Day=newDateTime(2013,1,1),Value=2},
新的DailyConsumption{Day=new DateTime(2013,1,5),Value=1}
}
});
var结果=
monthlyConsumptions.OrderBy(
x=>
x、 DailyConsumptions.Where(y=>y.Day.Date==targetDay.Date)。选择(
z=>(!z.Value.HasValue?0:z.Value.Value)).SingleOrDefault()).ToList();
Assert.AreEqual(“第二个”,结果[0]。单位);
}
}
如您所见,
Assert
确认第二个项目确实放在了第一位,因为“second”的Jan 1st值低于“first”。

请尝试:

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);
这将获取所有
月消费的所有
日消费
,然后仅过滤1月1日的消费,按
值对其排序,而不是从中获取任何数据,它返回父实体,即
月消费

因此,您可以按照自己的意愿订购
iquirable


编辑:这将在LINQ中适用于实体,在您的情况下可能并不不幸,除非您在
DailyConsumption
中有父属性调用
MonthlyConsumption

恐怕我把我的问题用错词了,请参见我帖子中的编辑部分。+1-谢谢jeremy,我与orderby有过这样的问题,然后,在这样一个简单的属性上,你的“min”为我指明了正确的方向。这是由于深层次的linq结构!!然而,我现在将永远知道如何应对它们——干杯!我也是这样想的,所以我甚至可以编写monthyConsumptions.OrderBy(x=>x.DailyConsumptions.where(y=>y.DayDay==1)),但在我和你的例子中,我有一个错误:至少有一个对象必须实现IComparable我认为这可能与值为null有关我只是稍微修改了一下。试一试,我甚至把我的班从双人改成了双人?若要加倍,则不存在null,问题是相同的:至少必须有一个对象实现IComparableJust Edit my answer,添加一个单元测试来显示它的工作情况。不确定你的错误原因。
[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);
    }
}
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);