如何表述GroupJoin()语句



我有一个数据库,看起来(简化)如下:

var reports = new[] {
    new { ReportId = 1, Title = "Report A" },
    new { ReportId = 2, Title = "Report B" },
};
var testCases = new[] {
    new { TestId = 1, Title = "Test A" },
    new { TestId = 2, Title = "Test B" },
    new { TestId = 3, Title = "Test C" },
    new { TestId = 4, Title = "Test D" },
    new { TestId = 5, Title = "Test E" },
};
var testRuns = new[] {
    new { TestId = 1, ReportId = 1 },
    new { TestId = 2, ReportId = 1 },
    new { TestId = 1, ReportId = 2 },
    new { TestId = 2, ReportId = 2 },
    new { TestId = 3, ReportId = 2 },
    new { TestId = 4, ReportId = 2 },
};

因此,我想获得与相应的reports分组的testCases列表,即:

Test A => [Report A, Report B]
Test B => [Report A, Report B]
Test C => [Report B]
Test D => [Report B]
Test E => []

我不确定如何在SQL或LINQ中制定此。我想我需要一个组连接或左外连接或不管它叫什么,但我不能找出正确的语法。我尝试了这样的东西,但仍然遗漏了一部分:

var result = tests.GroupJoin(reports, t => t.TestId, ???, (t, rs) => new { Test = t, Reports = rs });

或者可能有一种完全不同的方式来表达这个查询。

编辑:并非testCases中的每个条目都在testRuns中引用。

如果你可以不使用GroupJoin,你可以使用2个简单的连接和一个GroupBy,像这样:

var temp = from c in testCases
           join ru in testRuns
           on c.TestId equals ru.TestId into left
           from l in left
           join re in reports 
           on l.ReportId equals re.ReportId into foo
           from f in foo
           select new {
                Test = c.Title,
                Report = f
           };
//Dump only in LinqPad!            
temp.GroupBy(x => x.Test).Dump();

/EDIT:如果您还想要空结果,您需要使用DefaultIfEmpty():

public class Report
{
    public int ReportId { get; set; }
    public string Title { get; set; }
}
public class TestCase
{
    public int TestId { get; set; }
    public string Title { get; set; }
}
public class TestRun
{
    public int TestId { get; set; }
    public int ReportId { get; set; }
}
var temp = from c in testCases
           join ru in testRuns
           on c.TestId equals ru.TestId into left
           from l in left.DefaultIfEmpty(new TestRun())
           join re in reports 
           on l.ReportId equals re.ReportId into foo
           from f in foo.DefaultIfEmpty()
           select new {
                Test = c.Title,
                Report = f 
           };
temp.Dump();
  • 演示代码:http://share.linqpad.net/t3osbj.linq
  • 使用DefaultIfempty的强类型演示:http://share.linqpad.net/fsov4p.linq
  • 带有DefaultIfEmpty的松散类型示例:http://share.linqpad.net/7k2lq4.linq

我认为您不需要组连接。这会给你你所需要的。结果将包含一个测试id以及与它相关联的报告。

var result = testRuns.GroupBy(tr => tr.TestID)
                     .Select(t => new { 
                                       TestID = t.Key,
                                       Reports = t.Select(r => r.ReportID).ToList()
                                      });

相关内容

  • 没有找到相关文章