使用 LINQ 查询排除特定记录

Posted

技术标签:

【中文标题】使用 LINQ 查询排除特定记录【英文标题】:Excluding specific records using LINQ query 【发布时间】:2013-05-09 13:13:27 【问题描述】: StudentID 会话学期主题 1 2012 1 1 1 2012 1 2 1 2012 1 3 1 2012 1 4 1 2012 1 5 1 2012 2 6 1 2012 2 7 1 2012 2 8 1 2012 2 9 1 2012 2 10 1 2013 2 1 1 2013 2 13 1 2013 2 14 1 2013 2 15 1 2013 2 16 1 2013 3 17 1 2013 3 18 1 2013 3 19 1 2013 3 20 1 2013 3 21

我不知道我可以为我想要生成的查询命名。我搜索了很多,但找不到任何结果。 我想要做的是编写一个查询,它可以帮助我选择第 1,2 和 3 学期的记录,但要排除不同会话的同一学期的记录。具体来说(我想检索2012年的第一学期和2013年的第二学期和第三学期)。 此操作在未指定的会话和学期中重复。

【问题讨论】:

你能写出你想检索的数据吗,比如上表?我的意思是你能写出结果数据表吗? @AliRızaAdıyahşi 我想选择 2012 年第 1 学期以及 2013 年第 2 和第 3 学期 @AqilAzad:你为什么要这样做?鉴于表格,您为什么需要这样做没有任何意义。 用户 是否告诉您他们想要的年份/学期?或者这只是“我想要这个查询的结果”的简单案例? 如果我对查询的理解正确,我认为 Aqil 想选择每个学期的最小会话。诚然,这样的查询对于课程多次出现并且我们想选择最早的课程是有意义的。 @sixlettervariables 我实际上想为学院的学生生成成绩单。他们可能在特定课程的特定学期失败。他们一定会参加下一届,并在新届中获得同一学期的成绩。我想要的是我不想错过以前的结果。我只想选择新学期和以前的学期,这些学期在其他课程中没有重复。我认为这对我的客户来说是有意义的。 【参考方案1】:

我不知道该查询要表示什么,但您当然可以使用 LINQ 来实现该结果。

Where 将帮助您缩小结果,SelectMany 将帮助您加入多个序列。

var studentData = ...; // your table of data

var studentId = ...; // student Id

var requestedRecords = new [] 
    
        new  Session = 2012, Semester = 1 ,
        new  Session = 2013, Semester = 2 ,
        new  Session = 2013, Semester = 3 ,
    ;

var query = requestedRecords.SelectMany(
                rr => studentData.Where(
                          ss => ss.StudentID == studentId
                             && ss.Session == rr.Session 
                             && ss.Semester == rr.Semester)
            );

【讨论】:

【参考方案2】:

它在 Linqpad 中:

var tuples = new[] 
Tuple.Create(1, 2012, 1, 1),
Tuple.Create(1, 2012, 1, 2),
Tuple.Create(1, 2012, 1, 3),
Tuple.Create(1, 2012, 1, 4),
Tuple.Create(1, 2012, 1, 5),
Tuple.Create(1, 2012, 2, 6),
Tuple.Create(1, 2012, 2, 7),
Tuple.Create(1, 2012, 2, 8),
Tuple.Create(1, 2012, 2, 9),
Tuple.Create(1, 2012, 2, 10),
Tuple.Create(1, 2013, 2, 1),
Tuple.Create(1, 2013, 2, 13),
Tuple.Create(1, 2013, 2, 14),
Tuple.Create(1, 2013, 2, 15),
Tuple.Create(1, 2013, 2, 16),
Tuple.Create(1, 2013, 3, 17),
Tuple.Create(1, 2013, 3, 18),
Tuple.Create(1, 2013, 3, 19),
Tuple.Create(1, 2013, 3, 20),
Tuple.Create(1, 2013, 3, 21);
tuples
    .GroupBy(t => t.Item3)
    .Select (g => g.Where(x => x.Item2 == g.Max (x1 => x1.Item2)))
    .Dump();

因此,您将获得一个学期中最高年份的学期。

输出:

Item1 Item2 Item3 Item4 
1 2012 1 1 
1 2012 1 2 
1 2012 1 3 
1 2012 1 4 
1 2012 1 5 

Item1 Item2 Item3 Item4 
1 2013 2 1 
1 2013 2 13 
1 2013 2 14 
1 2013 2 15 
1 2013 2 16 

Item1 Item2 Item3 Item4 
1 2013 3 17 
1 2013 3 18 
1 2013 3 19 
1 2013 3 20 
1 2013 3 21 

【讨论】:

【参考方案3】:

LINQ 'Except' 方法

我想你可能对LINQ 'Except' method 感兴趣。

【讨论】:

谢谢,但我找不到选择排除项的查询。我的意思是我无法查询 2012 年第 2 学期 如果事先知道需要排除的内容,Except 将起作用。我认为这在这里行不通。【参考方案4】:

我认为您需要在这里进行自我加入。您将需要首先进行分组并获取每个会话/学期组合的 min(session),然后您希望将此结果与完整表再次加入会话和学期。

这里是a very good resource for LINQ samples。我手头没有我的LINQpad,否则我会为你搞砸的。

我通常不会推荐产品,但 LINQPad 在设计 LINQ 查询甚至 C# sn-ps 原型时是一种美感。

SQL 将如下所示:

SELECT
    *
FROM
    Course AS C
    INNER JOIN
    (
        SELECT
            MIN(IC.Session),
            IC.Semester
        FROM
            Course AS IC
        GROUP BY
            IC.Session,
            IC.Semester
    ) AS Q ON C.Session = Q.Session AND C.Semester = Q.Semester

【讨论】:

我想我按照你说的做了。即使是 SQL,您也可以编写您的查询 不幸的是结果不同 尝试 MAX 而不是 MIN。我认为这应该可以解决您的问题。

以上是关于使用 LINQ 查询排除特定记录的主要内容,如果未能解决你的问题,请参考以下文章

查询排除了json值且json键不存在的记录

排除特定记录时的随机 SQL 记录

如何从 Rails 中的查询中排除 id 数组(使用 ActiveRecord)?

排除 Qubole 中具有特定值的记录

SQL查询;如果子记录 = 条件则排除记录

使用 Linq 查询 XML 文档