连接多个表时,避免在linq查询中出现重复记录

时间:2015-07-11 08:26:24

标签: sql-server wpf linq entity-framework

我的数据库中有以下标签

TestPack { id, name, type }
Documentation { id, tp_id, date, rev }
Flushing { id, tp_id, date, rev }

tp_Id是TestPack ID,是Documentation和Flushing表中的外键,这意味着TestPack可能具有1-N Documentations和Flushings。

现在我想查询数据库(使用EF LINQ)返回测试包,以及针对一个Test Pack的所有Documentations和Flushings,以便我可以在一个DataGrid中显示所有这些信息?

没有任何Documentatoin / Flushings的测试包也应该显示在结果中。

这是我到目前为止撰写的查询

 internal List<TestPackRegister> GenerateReport2()
{
    var allTestPacks = Project.GetAllTestPacks();
    var allDocumentation = Project.GetAllDocoumentations();
    var allFlushings = Project.GetAllPreTestFlushings();

    var queryResult = from tp in allTestPacks

        join doc in allDocumentation on tp.id equals doc.test_pack_id.Value
        into tpDoc
        from subtpDoc in tpDoc.DefaultIfEmpty()

        join flushings in allFlushings on tp.id equals flushings.test_pack_id.Value
        into tpFlings
        from subtpflushings in tpFlings.DefaultIfEmpty()

        select new TestPackRegister
        {
            test_pack_no = tp.test_pack_no,

            Documentation_Notification = subtpDoc != null ? subtpDoc.const_notification_no : null,
            Documentation_Rev = subtpDoc != null ? subtpDoc.const_notification_no_rev : null,
            Documentation_Notification_Date = subtpDoc != null ? subtpDoc.const_notification_date : null,
            Documentation_TargetReadiness_Date = subtpDoc != null ? subtpDoc.doc_readiness_target_date : null,
            Documentation_ActualReadiness_Date = subtpDoc != null ? subtpDoc.doc_readiness_date : null,
            Documentation_Remarks = subtpDoc != null ? subtpDoc.remarks : null,

            Flushing_RFI = subtpflushings != null ? subtpflushings.RFINo : null,
            Flushing_Rev = subtpflushings != null ? subtpflushings.rfi_rev_no : null,
            Flushing_RFI_Date = subtpflushings != null && subtpflushings.rfi_date != null ? subtpflushings.rfi_date : null,
            Flushing_Planned_Date = subtpflushings != null && subtpflushings.planned_date != null ? subtpflushings.planned_date : null,
            Flushing_Actual_Date = subtpflushings != null && subtpflushings.actual_date != null ? subtpflushings.actual_date : null,
            Flushing_Acceptance_Date = subtpflushings != null && subtpflushings.acceptance_date != null ? subtpflushings.acceptance_date : null,
            Flushing_Remarks = subtpflushings != null ? subtpflushings.remarks : null,
        };

    QueryResult = queryResult.ToList();
    return QueryResult;
}

以下是查询结果

enter image description here

基本上在我的TestPack表中,我有2个testPack。 Test Pack 1有2个Documentations和2个Flushing记录,而Test Pack 2只有1个Documentation和1个Flushing记录。 所以我关注的是TestPack#1显示四行,它不应该显示两行吗?因为测试包有2个冲洗和1个testPack的2个文档。所以它们都应该出现在2行中?为什么他们出现在四排?我该如何纠正这种行为?

1 个答案:

答案 0 :(得分:0)

我也陷入了困境。这是我的方法:

foreach (var tp in allTestPacks)
        {
            var lstAllFlh = allFlushings.Where(m => m.TpID == tp.IDTP).ToList();
            var lstAllDoc = allDocumentation.Where(m => m.TpID == tp.IDTP).ToList();
            foreach (var flh in lstAllFlh)
                lstResult.Add(new { TPID = tp.IDTP, TPName = tp.Value, DocName = lstAllDoc.Skip(lstAllFlh.FindIndex(f => f == flh) % lstAllDoc.Count).First().Value, FlushName = flh.Value });
        }