【问题标题】:EF Left joining a table on two properties combined with a case statementEF Left 将两个属性的表与 case 语句相结合
【发布时间】:2012-12-18 18:06:59
【问题描述】:

我正在尝试为数据库编写一个查询,该查询将左连接一个表到一个查找表,结果将根据 case 语句返回。

在普通 SQL 中,查询如下所示:

SELECT chis_id, chis_detail, cilt.mhcatID, cilt.mhtID, 'TheFileName' =
CASE  
    WHEN cilt.mhcatID IS NOT NULL AND cilt.mhtID IS NOT NULL THEN chis_linked_filename
    END
FROM chis
    LEFT JOIN cilt on cilt.mhcatID = chis.mhcat_id AND cilt.mhtID = chis.mht_id 
WHERE cch_id = 50

chis 是被查询的表,cilt 是一个查找表,因此不包含与 chis 的任何外键关系(chis 具有分别通过 mhtID 和 mhcatID 的 mht 和 mhcat 表的现有 FK )。

查询将用于返回记录的历史更新列表。如果连接到 cilt 查找表成功,这意味着查询的调用者将有权查看任何关联文件的文件名以进行历史更新。

虽然在我的研究过程中,我在这里找到了各种关于如何在 Linq 中进行案例陈述和左连接到实体查询的帖子,但我无法弄清楚如何在两个不同的领域进行连接。这可能吗?

【问题讨论】:

    标签: entity-framework entity-framework-4 linq-to-entities left-join case-statement


    【解决方案1】:

    您需要加入具有匹配字段名称的匿名类型,如下所示:

    var query = from x in context.Table1
                join y in context.Table2
                on new { x.Field1, x.Field2 } equals new { y.Field1, y.Field2 }
                select {...};
    

    使用额外的from 而不是join 的完整工作示例如下所示:

    var query = from chis in context.Chis
                from clit in context.Clit
                                    .Where(x => x.mhcatID = chis.mhcat_id)
                                    .Where(x =>  x.mhtID = chis.mht_id)
                                    .DefaultIfEmpty()
                select new
                {
                  chis.id, 
                  chis.detail, 
                  cilt.mhcatID, 
                  cilt.mhtID,
                  TheFileName = (cilt.mhcatID != null && cilt.mhtID != null) ? chis.linked_filename : null
                };
    

    【讨论】:

    • 出于兴趣,是否存在任何性能问题或使用“from”的解决方案比匿名类型方法更好/更差的原因?
    • @GrandMasterFlush - 根据我的经验,两种方法生成的 SQL 是相同的,所以我会选择你觉得更容易的选项。
    • 我刚刚检查了结果,这是作为内连接而不是左连接传递给数据库的。即使我将查询简化为以下内容,它仍然作为内部连接处理:var query = from x in context.chis join y in context.cilts on new { MHT = x.mht_id } 等于 new { MHT = y。 mhtID } 其中 x.cch_id == 50 选择 x.chis_id;
    • @GrandMasterFlush - 您需要使用 DefaultIfEmpty() 进行左连接。
    【解决方案2】:

    根据 Aducci 的建议,我使用了组加入和 DefaultIsEmpty() 来获得我想要的结果。由于某种原因,我无法让 DefaultIfEmpty() 无法正常工作,并且生成的 SQL 使用了内连接而不是左连接。

    这是我用来让左连接工作的最终代码:

    var query = (from chis in context.chis
                 join cilt in context.cilts on new { MHT = chis.mht_id, MHTCAT = chis.mhcat_id } equals new { MHT = cilt.mhtID, MHTCAT = cilt.mhcatID } into tempCilts
                 from tempCilt in tempCilts.DefaultIfEmpty()
                 where chis.cch_id == 50
                 select new { 
                                 chisID = chis.chis_id, 
                                 detail = chis.chis_detail, 
                                 filename = chis.chis_linked_filename, 
                                 TheFileName = (tempCilt.mhcatID != null && tempCilt.mhtID != null ? chis.chis_linked_filename : null), 
                                   mhtID = chis.mht_id, 
                                   mhtcatID = chis.mhcat_id 
                            }).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 2021-11-23
      • 2022-12-06
      • 1970-01-01
      相关资源
      最近更新 更多