0

編集 3: 質問の文言と例の改善

グループ化を使用する次の linq クエリがあります。グループ化と選択の操作は複雑なので、選択の 1 つを、データのレンダリング方法を選択するメソッドに抽象化しました。

私のクエリは匿名グループ定義内では正しく機能しますが、それを 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();
    }
}
4

1 に答える 1

2

最初のケースでは、コンパイラによって生成された匿名タイプでグループ化します。このタイプは、EqualsおよびHashCodeオーバーライドも生成しました(ildasmを介して確認できます)。匿名タイプのデフォルトのEqualsは、各フィールドに対して等式比較を実行します。このような場合に使用するために作られたと思います。

2番目のケースでは、カスタムタイプでグループ化します。これは参照型であるため、デフォルトの等式比較器は参照によってオブジェクトを比較します。グループ化する前に一連のオブジェクトを作成するため、それぞれが一意です。したがって、デフォルトの同等性チェックは、それらが異なると見なします。

解決策は次のとおりです(いずれかを選択してください):

  1. EqualsとHashCodeをオーバーライドします。
  2. struct代わりにタイプを作成class

注意して、HashCodeも実装することを忘れないでください。

于 2013-02-20T00:14:17.527 に答える