【问题标题】:Method that receives LINQ IGrouping as Parameter接收 LINQ IGrouping 作为参数的方法
【发布时间】:2013-02-20 08:14:17
【问题描述】:

编辑 3:改进的问题措辞和示例

我有以下使用分组的 linq 查询。分组和选择操作很复杂,因此我将其中一个选择抽象为一种方法,该方法对如何呈现数据做出一些选择。

我的查询在匿名组定义中可以正常工作,但是一旦我将其键入到类中以便将其作为 IGrouping 对象传递给方法,它就会停止对结果进行分组。

public class TestController : Controller
{
    public JsonResult ThisWorks()
    {
        var valueList = DataMocker.GetTestValues();

        var group = from v in valueList.AsEnumerable()
                    where (v.Data != 0)
                    group v by new 
                                   {
                                       Year = v.Fecha.Value.Year,
                                       Trimester = string.Empty,
                                       Month = v.Fecha.Value.Month,
                                       Day = 0,
                                   }
                        into g
                        select new SeriesDataPoint
                                                     {
                                                         y = g.OrderByDescending(obd => obd.Fecha)
                                                                  .Select(obd => obd.Data.Value)
                                                                  .FirstOrDefault(),

                                                         color = "black",
                                                         month = g.Key.Month,
                                                         year = g.Key.Year,
                                                         seriesName = "Test Series",
                                                     };

        return Json(group, JsonRequestBehavior.AllowGet);
    }

    public JsonResult ThisDoesnt()
    {
        var valueList = DataMocker.GetTestValues();

        var group = from v in valueList.AsEnumerable()
                    where (v.Data != 0)
                    group v by new Models.SeriesResultGroup
                    {
                        Year = v.Fecha.Value.Year,
                        Trimester = string.Empty,
                        Month = v.Fecha.Value.Month,
                        Day = 0,
                    }
                        into g
                        select new SeriesDataPoint
                        {
                            y = RenderDataPoint(valueList, g),
                            color = "black",
                            month = g.Key.Month,
                            year = g.Key.Year,
                            seriesName = "Test Series",
                        };

        return Json(group, JsonRequestBehavior.AllowGet);
    }

    public static decimal? RenderDataPoint(List<Models.ValoresResultSet> valores, IGrouping<Models.SeriesResultGroup, Models.ValoresResultSet> group)
    {
        return group.OrderByDescending(obd => obd.Fecha)
                    .Select(obd => obd.Data.Value)
                    .FirstOrDefault();
    }
}

【问题讨论】:

  • “不工作”不是错误描述。请解释发生了什么。如果您收到错误消息,请将其发布。如果您没有得到想要的结果,请发布预期和实际结果。
  • 您在此问题中的代码与您链接到的文件中的代码不匹配。
  • @DanielHilgarth 对不起,不够明确。代码编译并运行,但分组没有按预期工作。事实上,它根本不起作用,我把所有行都找回来了
  • 什么是 Models.SeriesResultGroup ?如果它是一个没有重写 Equals 的类,那么每个对象在相等性方面都是唯一的
  • 嗨,艾哈迈德。在这种情况下真正有帮助的是你不断地从你的方法中删除,直到它尽可能简单,但仍然可以证明问题。目前还不清楚。

标签: c# linq linq-to-entities


【解决方案1】:

在第一种情况下,您按匿名类型分组,由编译器生成。这种类型还生成了 Equals 和 HashCode 覆盖(您可以通过 ildasm 检查它)。匿名类型的默认 Equals 为每个字段运行相等比较器。我认为这是为了在这种情况下使用。

在第二种情况下,您按自定义类型分组。由于它是引用类型,默认相等比较器通过引用比较对象。因为在分组之前你会产生一系列对象,每个对象都是独一无二的。所以默认相等检查认为它们不同。

解决方案是(任意选择):

  1. 覆盖 Equals 和 HashCode。
  2. 输入struct 而不是class

要小心,不要忘记实现 HashCode。

【讨论】:

    猜你喜欢
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2012-05-08
    • 1970-01-01
    • 2021-10-19
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多