简体   繁体   English

Linq查询:最大(日期)时选择ID的内容

[英]Linq query : select content of an ID when max(date)

Happy new Year everyone ! 祝大家新年快乐 ! :-) :-)

I've searched for several hours but I can't figure out how to build my query properly using Linq. 我搜索了几个小时,但无法弄清楚如何使用Linq正确构建查询。

I have 2 tables : A and B 我有2张桌子:A和B

In table A : I have A_ID, B_ID, VALUE_DATE. 在表A中:我有A_ID,B_ID,VALUE_DATE。

In table B : I have B_ID, STATUS. 在表B中:我有B_ID,STATUS。

Example : 范例:

A_ID = 547 VALUE_DATE = 01/05/10 B_ID = 14750 A_ID = 547 VALUE_DATE = 01/05/10 B_ID = 14750

A_ID = 547 VALUE_DATE = 01/10/10 B_ID = 14750 A_ID = 547 VALUE_DATE = 01/10/10 B_ID = 14750

I want to join A and B using B_ID where VALUE_DATE is max. 我想使用B_ID(其中最大VALUE_DATE)加入A和B。 At the moment, this is what I have : 目前,这就是我所拥有的:

context is OracleDataContextCommon object evalId and listAffId are parameters of my webservice method. 上下文是OracleDataContextCommon对象evalId和listAffId是我的Web服务方法的参数。

var query = (from tabA in (from a in context.A
                          where listAffId.Contains(a.A_ID)
                          group a by a.A_IDinto grp
                          select new
                          {
                              pId = (int)grp.Key,
                              valDate = grp.Max(x => x.ValueDate),
                              bId = grp.Select(x => B_ID).FirstOrDefault()
                          })
                         join tabB in context.B on tabA.bIdequals equals tabB.B_ID
                         select new
                         {
                             affId = tabA.pId,
                             status = tabB.Status
                         });

Where am I wrong ? 我哪里错了? Thank you for investigate... 谢谢您的调查...

The problem is that you're taking the max Date of the Group, but you are selecting the FirstOrDefault B_ID in the group, which doesn't necessarily correlate with the A row which had the max date. 问题是您要使用组的最大日期,但是要在组中选择FirstOrDefault B_ID ,它不一定与具有最大日期的A行相关。 Easiest is probably to just order the data by date descending before grouping, and then take the first item in each group for both date and b_id . 最简单的方法可能是按照分组之前的降序对数据进行排序,然后对date和b_id进行每组中的第一项。

Note that I've switched your context for with some dummy data below. 请注意,我在下面用一些虚拟数据切换了您的上下文。

var theAs = new[]
{
   new {A_ID = 547, ValueDate = new DateTime(2010, 05, 01), B_ID = 14750}, 
   new {A_ID = 547, ValueDate = new DateTime(2010, 10, 01), B_ID = 14751}
};
var theBs = new[]
{
  new {B_ID = 14750, Status = "Foo"}, 
  new {B_ID = 14751, Status = "Bar"}
};
var listAffId = new[]{547};

var query = (from tabA in (from a in theAs
             where listAffId.Contains(a.A_ID)
             // Order the data - the first row per group is thus max date
             orderby a.ValueDate descending
             group a by a.A_ID into grp
             select new
             {
                 pId = (int)grp.Key,
                 // Now pull the date and B_ID from the same row
                 valDate = grp.First().ValueDate,
                 bId = grp.First().B_ID
             })
             join tabB in theBs on tabA.bId equals tabB.B_ID
             select new
             {
                 affId = tabA.pId,
                 status = tabB.Status
             });

I simulated code with classes. 我用类模拟了代码。 I think this should work 我认为这应该工作

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Context context = new Context();
            List<int> listAffId = new List<int>() { 547 };

            var query = (from a in context.A where listAffId.Contains(a.A_ID)
                         join b in context.B on a.B_ID equals b.B_ID
                         select new { a = a, b = b})
                         .GroupBy(x => x.a.A_ID)
                         .Select(x => new { x = x, max = x.Max(y => y.a.VALUE_DATE)})
                         .Select(x => new {
                             affId = x.x.Key,
                             status = x.x.Where(y => y.a.VALUE_DATE == x.max).Select(y => y.b.STATUS).FirstOrDefault()
                         }).ToList();



        }
    }
    public class Context
    {
        public List<TableA> A { get; set; }
        public List<TableB> B { get; set; }
    }
    public class TableA
    {
        public int A_ID { get; set; }
        public int B_ID { get; set; }
        public DateTime VALUE_DATE { get; set; }
    }
    public class TableB
    {
        public int B_ID { get; set; }
        public string STATUS { get; set; }
    }
}

You need to select the B_ID that is for the max date, so find the max date first: 您需要选择最大日期的B_ID ,因此请首先找到最大日期:

var query = (from tabA in (from a in context.A
                          where listAffId.Contains(a.A_ID)
                          group a by a.A_IDinto grp
                          let maxdate = grp.Max(a => a.ValueDate)
                          select new
                          {
                              pId = (int)grp.Key,
                              valDate = maxdate,
                              bId = grp.Where(a => a.ValueDate == maxdate).Select(x => B_ID).FirstOrDefault()
                          })
                         join tabB in context.B on tabA.bId equals equals tabB.B_ID
                         select new
                         {
                             affId = tabA.pId,
                             status = tabB.Status
                         });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM