Преобразование GROUP BY / MIN DATE с SQL в LINQ - PullRequest
1 голос
/ 03 августа 2020

У меня проблемы с переводом моего SQL в LINQ, чтобы работать с ожидаемым результатом ...

Рассмотрим следующую таблицу:

pkIdentifier  fkProject    fkFirst     fkSecond    Date
1             1030         1           1           03.08.2020 10:05:00
2             1030         1           2           03.08.2020 10:11:00
3             1030         3           1           03.08.2020 14:00:00
4             1030         3           2           03.08.2020 14:02:00
5             1040         1           1           03.08.2020 15:00:00
6             1050         2           1           04.08.2020 08:00:00
7             1050         2           2           04.08.2020 08:10:00
8             1050         2           3           04.08.2020 08:15:00

Что мне здесь нужно состоит в том, чтобы найти проекты с наибольшим значением "fkSecond" - и если есть больше записей, то тот с самой молодой датой.

Это означает, что результат для приведенной выше таблицы будет:

pkIdentifier  fkProject    fkFirst     fkSecond    Date
2             1030         1           2           03.08.2020 10:11:00
5             1040         1           1           03.08.2020 15:00:00
8             1050         2           3           04.08.2020 08:15:00

С SQL ниже, это почти тот же результат, что я ожидал:

SELECT ps.fkProject, ps.fkFirst, ps.fkSecond, min(ps.Date) as Date
FROM ProjectsStatus ps
    INNER JOIN (
        SELECT a.fkProject, MAX(a.fkSecond) as maxSecond
        FROM ProjectStatus a
        GROUP BY a.fkProject
    ) b ON ps.fkProject = b.fkProject and ps.fkSecond = b.maxSecond
group by ps.fkProject, ps.First, ps.Second

Моя попытка LINQ, но отсутствует выбор только записей с самой молодой датой, если есть есть еще записи с тем же "fkSecond":

var query = this.dataContext.ProjectStatus.Where(
            x => x.fkSecond == this.dataContext.ProjectStatus.Where(y => y.fkProject == x.fkProject).Max(s => s.fkSecond)
          );

В настоящее время я также получаю вторую строку с fkSecond = 2 для Project 1030, но это не то, что я хочу. Мне нужен только тот, у которого самый младший Date, с pkIdentifier 2.

pkIdentifier  fkProject    fkFirst     fkSecond    Date
2             1030         1           2           03.08.2020 10:11:00
4             1030         3           2           03.08.2020 14:02:00
5             1040         1           1           03.08.2020 15:00:00
8             1050         2           3           04.08.2020 08:15:00

Ответы [ 2 ]

0 голосов
/ 03 августа 2020

Вы можете использовать GroupBy, как показано в следующем примере:

class Data
{
    public int pkIdentifier { get; set; }
    public int fkProject { get; set; }
    public int fkFirst { get; set; }
    public int fkSecond { get; set; }
    public DateTime date { get; set; }
}

List<Data> dataList = new List<Data>();

dataList.Add(new Data { pkIdentifier = 1, fkProject = 1030, fkFirst = 1, fkSecond = 1, date = new DateTime(2020, 08, 03, 10, 05, 00) });
dataList.Add(new Data { pkIdentifier = 2, fkProject = 1030, fkFirst = 1, fkSecond = 2, date = new DateTime(2020, 08, 03, 10, 11, 00) });
dataList.Add(new Data { pkIdentifier = 3, fkProject = 1030, fkFirst = 3, fkSecond = 1, date = new DateTime(2020, 08, 03, 14, 00, 00) });
dataList.Add(new Data { pkIdentifier = 4, fkProject = 1030, fkFirst = 3, fkSecond = 2, date = new DateTime(2020, 08, 03, 14, 02, 00) });
dataList.Add(new Data { pkIdentifier = 5, fkProject = 1040, fkFirst = 1, fkSecond = 1, date = new DateTime(2020, 08, 03, 15, 00, 00) });
dataList.Add(new Data { pkIdentifier = 6, fkProject = 1050, fkFirst = 2, fkSecond = 1, date = new DateTime(2020, 08, 04, 08, 00, 00) });
dataList.Add(new Data { pkIdentifier = 7, fkProject = 1050, fkFirst = 2, fkSecond = 2, date = new DateTime(2020, 08, 04, 08, 10, 00) });
dataList.Add(new Data { pkIdentifier = 8, fkProject = 1050, fkFirst = 2, fkSecond = 3, date = new DateTime(2020, 08, 04, 08, 15, 00) });

var groupProject = dataList.GroupBy(i => i.fkProject).Select(groupItem => groupItem.OrderByDescending(dataItem => dataItem.fkSecond).ThenBy(dataItem => dataItem.date).First());

GroupBy будет группироваться по номеру проекта, а затем упорядочиваться по fkSecond, а затем по убыванию даты. Затем берется первый элемент в каждой группе.

0 голосов
/ 03 августа 2020

См. Ниже:

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

namespace ConsoleApplication163
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();

            dt.Columns.Add("pkIdentifier", typeof(int));
            dt.Columns.Add("fkProject", typeof(int));
            dt.Columns.Add("fkFirst", typeof(int));
            dt.Columns.Add("fkSecond", typeof(int));
            dt.Columns.Add("Date", typeof(DateTime));
            
            dt.Rows.Add(new object[] { 1, 1030, 1, 1, new DateTime(2020, 3, 8, 10, 5, 0)});
            dt.Rows.Add(new object[] { 2, 1030, 1, 2, new DateTime(2020, 3, 8, 10, 11, 0)});
            dt.Rows.Add(new object[] { 3, 1030, 3, 1, new DateTime(2020, 3, 8, 14, 0, 0)});
            dt.Rows.Add(new object[] { 4, 1030, 3, 2, new DateTime(2020, 3, 8, 14, 2, 0)});
            dt.Rows.Add(new object[] { 5, 1040, 1, 1, new DateTime(2020, 3, 8, 15, 0, 0)});
            dt.Rows.Add(new object[] { 6, 1050, 2, 1, new DateTime(2020, 3, 8, 8, 0, 0)});
            dt.Rows.Add(new object[] { 7, 1050, 2, 2, new DateTime(2020, 3, 8, 8, 10, 0)});
            dt.Rows.Add(new object[] { 8, 1050, 2, 3, new DateTime(2020, 3, 8, 8, 15, 0)});

            DataTable dt2 = dt.AsEnumerable()
                .OrderBy(x=> x.Field<int>("fkProject"))
                .ThenByDescending (x => x.Field<int>("fkSecond"))
                .ThenBy(x => x.Field<DateTime>("Date"))
                .GroupBy(x => x.Field<int>("fkProject"))
                .Select(x => x.First())
                .CopyToDataTable();

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...