LINQ(和 SQL)按不同属性获取最新条目

本文关键字:获取 属性 最新 SQL LINQ | 更新日期: 2023-09-27 18:32:59

我有一个包含以下相关列的表格:

  • 机器 [键]
  • 样本
  • 实验
  • 完成日期
  • 。我对其执行一些计算的一些测试值

结构

Machine - Sample - Experiment - Completed - ...
m1      - s1     - e1         - <date>    - ...
m1      - s1     - e2         - <date>    - ...
m1      - s2     - e1         - <date>    - ...
....
m2      - s3     - e1         - <date>    - ...
....

在每台机器上,可以对单个样品进行多个实验。

我的目标是确定每台机器的 5 个最新不同样本,并获取所有相关条目(整行,包括每个样本的所有实验(。

一旦我按

机器分组并按完成日期降序排序,我似乎找不到下一步。

我想需要某种"DistinctBy (x => x.Sample(",但没有设法解决。

例:(说已经按日期降序排序了(

Machine - Sample - Experiment
m1 - s1 - e1 * 
m1 - s1 - e2 *
m1 - s2 - e1 *
m1 - s2 - e2 *
m1 - s3 - e1 *
m1 - s4 - e1 *
m1 - s4 - e2 *
m1 - s5 - e1 *
m1 - s6 - e1
m1 - s6 - e2
...

我需要所有标记为"*"的行作为查询的输出 - 对于每台机器。

我甚至为此编写SQL语句都在苦苦挣扎。如果你知道如何用SQL写这个,发布它,我也可能从中得到一些东西。

编辑:

好的,我再次尝试自下而上,我的第一次尝试是识别最新的 5 个样本。

以下具有固定值的查询有效

var samples = (from c in db.Experiments
           where c.Machine == "m1" 
           orderby c.Completed descending
           select c.Sample).ToList().Distinct().Take(5)

我需要添加"ToList((",因为 Distinct(( 会搞砸它。

现在,当我将其包含在另一个查询中时,我希望每台机器的结果 - 它不起作用 - 它不会按完成日期降序排序,而是保持"随机"顺序。

为什么会这样?

var last5samples = (from t in db.Experiments
                    group t by new { t.Machine } into g
                    select new
                    {
                        Machine = g.Key.Machine,
                        Samples = (from c in db.Experiments
                                   where c.Machine == g.Key.Machine 
                                   orderby c.Completed descending
                                   select c.Sample).ToList().Distinct().Take(5)
                    });

编辑2:

尝试了另一种方法,以征集我确实需要的东西 - 包含最后 5 个样本的所有行。这很慢,但"有效",有点,除了顺序下降不起作用。

我首先采用了"IN"方法,但后来发现使用 LINQ 我需要反转逻辑,这就是我想出的:

var last5samples = from t in db.Experiments
                   where (from c in db.Experiments
                          where c.Machine == t.Machine
                          orderby c.Completed descending
                          select c.Sample).ToList().Distinct().Take(5)
                   .Contains(t.Sample)
                   select t;

我现在的主要问题是如何按预期按降序工作进行排序。

我不明白为什么它是单独查询时有效,而当它是子查询时,它不起作用。

LINQ(和 SQL)按不同属性获取最新条目

LINQ 没有DistinctBy功能,但幸运的是,有一个名为 morelinq 的库可以让你做到这一点。

var results = query.DistinctBy(x => x.Sample).ToList();
using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public void Main()
    {
        var list = new List<Test>();
        list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-2) });
        list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-1) });
        list.Add(new Test { Machine = "m1", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now });
        list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-2) });
        list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddDays(-1) });
        list.Add(new Test { Machine = "m2", Sample = "s1", Experiment = "e1", DateCompleted = DateTime.Now.AddHours(-1) });
        var q = from s in list
                group s by new { s.Machine, s.Sample }
                    into gs
                    select new
                    {
                        Machine = gs.Key.Machine
                        ,
                        Sample = gs.Key.Sample
                        ,
                        Rows = gs.OrderByDescending(f => f.DateCompleted).Take(5)
                    };
        foreach (var p in q.ToList())
        {
            Console.WriteLine("{0} {1} {2}", p.Machine, p.Sample, p.Rows.Count());
        }
    }
}

public class Test
{
    public string Machine { get; set; }
    public string Sample { get; set; }
    public string Experiment { get; set; }
    public DateTime DateCompleted { get; set; }
}
好的,

这就是我解决它的方式。

在尝试了我能找到的任何内容之后,并且不明白为什么 distinct + orderby 在一种情况下("独奏"查询(而不是另一种情况(子查询(有效,我继续"以我的方式"这样做。

它的工作速度也足够快(比我在 EDIT 2 中编写的最新 LINQ 更快(。

在这里:

  1. 我得到所有不同的机器
  2. 对于每台机器,我获取最新的 5 个样品
  3. 对于每台机器,我获取包含最新 5 个样本的行

    foreach (var m in machines)
    {
    var last5Samples = (from t in db.Experiments
                    where t.Machine = m.Machine
                    orderby t.Completed descending
                    select t.Sample).ToList().Distinct().Take(5);
    var expsForLast5Samples = from t in db.Experiments
                          where last5Samples.Contains(t.Sample)
                          select t;
    }