如何使用Linq to Entities获取具有最新日期的记录组

时间:2018-05-18 10:20:18

标签: c# linq

我有一个包含以下字段的表:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

使用以下数据:

ID | MarketID | CommodityID | CurrencyID | PriceValue | Year | Month

如您所见,日期(不幸的是)在年份和月份字段中保存为整数。

我想从上述数据中获取,使用LINQ to Entities(EF6),每个Market-Commodity-Currency记录的最新PriceValue。

所以预期结果应为:

1  | 100 | 30 | 15 | 3.465 | 2018 | 03
2  | 100 | 30 | 15 | 2.372 | 2018 | 04
3  | 100 | 32 | 15 | 1.431 | 2018 | 02
4  | 100 | 32 | 15 | 1.855 | 2018 | 03
5  | 100 | 32 | 15 | 2.065 | 2018 | 04
6  | 101 | 30 | 15 | 7.732 | 2018 | 03
7  | 101 | 30 | 15 | 8.978 | 2018 | 04
8  | 101 | 32 | 15 | 4.601 | 2018 | 02
9  | 101 | 32 | 18 | 0.138 | 2017 | 12
10 | 101 | 32 | 18 | 0.165 | 2018 | 03
11 | 101 | 32 | 18 | 0.202 | 2018 | 04

我已经尝试了以下查询,但没有一个能够给我预期的结果:

2  | 100 | 30 | 15 | 2.372 | 2018 | 04
5  | 100 | 32 | 15 | 2.065 | 2018 | 04
7  | 101 | 30 | 15 | 8.978 | 2018 | 04
8  | 101 | 32 | 15 | 4.601 | 2018 | 02
11 | 101 | 32 | 18 | 0.202 | 2018 | 04

以下对前一个有更多感觉,但我放松了PriceValue字段:

var lastValues = (from a in Analysis
                     group a by a.ID into g
                     select g.OrderByDescending(t => ((t.Year* 100) + t.Month)));

有没有办法让单个LINQ查询只获取具有最新日期的记录,如上所述?

3 个答案:

答案 0 :(得分:1)

请尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication45
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("MARKETID", typeof(int));
            dt.Columns.Add("CommodityID", typeof(int));
            dt.Columns.Add("CurrencyID", typeof(int));
            dt.Columns.Add("PriceValue", typeof(decimal));
            dt.Columns.Add("Year", typeof(int));
            dt.Columns.Add("Month", typeof(int));
            //ID | MarketID | CommodityID | CurrencyID | PriceValue | Year | Month
            dt.Rows.Add(new object[] {1  , 100 , 30 , 15 , 3.465 , 2018 , 03});
            dt.Rows.Add(new object[] {2  , 100 , 30 , 15 , 2.372 , 2018 , 04});
            dt.Rows.Add(new object[] {3  , 100 , 32 , 15 , 1.431 , 2018 , 02});
            dt.Rows.Add(new object[] {4  , 100 , 32 , 15 , 1.855 , 2018 , 03});
            dt.Rows.Add(new object[] {5  , 100 , 32 , 15 , 2.065 , 2018 , 04});
            dt.Rows.Add(new object[] {6  , 101 , 30 , 15 , 7.732 , 2018 , 03});
            dt.Rows.Add(new object[] {7  , 101 , 30 , 15 , 8.978 , 2018 , 04});
            dt.Rows.Add(new object[] {8  , 101 , 32 , 15 , 4.601 , 2018 , 02});
            dt.Rows.Add(new object[] {9  , 101 , 32 , 18 , 0.138 , 2017 , 12});
            dt.Rows.Add(new object[] {10 , 101 , 32 , 18 , 0.165 , 2018 , 03});
            dt.Rows.Add(new object[] { 11, 101, 32, 18, 0.202, 2018, 04 });

            List<DataRow> results = dt.AsEnumerable()
                .OrderByDescending(x => new DateTime(x.Field<int>("Year"), x.Field<int>("Month"), 1))
                .GroupBy(x => new { market = x.Field<int>("MarketID"), commodity = x.Field<int>("CommodityID"), currency = x.Field<int>("CurrencyID") })
                .Select(x => x.First())
                .ToList();


        }

    }
}

答案 1 :(得分:0)

我终于找到了在结果中包含PriceValue的方法。

从我发布的最后一个查询开始,我只想添加

g.OrderByDescending(t => ((t.Year* 100) + t.Month)).FirstOrDefault().PriceValue

所以它会是:

var lastValues = (from a in Analysis
                  group a by new {a.MarketID, a.CommodityID, a.CurrencyID } into g
                  select new
                  {
                     g.Key.MarketID,
                     g.Key.CommodityID,
                     g.Key.CurrencyID,
                     date = g.Max(t => ((t.Year* 100) + t.Month)),
                     g.OrderByDescending(t => ((t.Year* 100) + t.Month)).FirstOrDefault().PriceValue
                  });

我更喜欢这个解决方案,因为它基于我开发的当前查询。

答案 2 :(得分:0)

尝试此Linq查询

     var lastValues = (from ak in Analysis
                          group ak by new { ak.MarketID, ak.CommodityID, ak.CurrencyID } into g
                          select new
                          {
                              g.Key.MarketID,
                              g.Key.CommodityID,
                              g.Key.CurrencyID,
                              pricevalue = g.OrderByDescending(c=>c.Year).ThenByDescending(c=>c.Month).FirstOrDefault().PriceValue,
                              year = g.OrderByDescending(c => c.Year).ThenByDescending(c => c.Month).FirstOrDefault().Year,
                              month = g.OrderByDescending(c => c.Year).ThenByDescending(c => c.Month).FirstOrDefault().Month
                          });

使用Orderby和ThenBy