Linq to Sql - 使用多个内部联接和多个参数

时间:2011-12-21 17:12:17

标签: c# linq-to-sql

到目前为止,我已经看到很多关于多个内部联接的SO问题,但没有一个能解决我的问题。我一直试图使用上一个表中的一个在2个表和第三个表上的子选择进行内连接。

这是sql代码:

SELECT 
//It's a lot of select fields here. Nothing really useful to solve the problem 
FROM 
    SCHEDULES
INNER JOIN 
    STATUS
ON
    SCHEDULES.COMPANY              = STATUS.COMPANY          AND 
    SCHEDULES.BANK                 = STATUS.BANK             AND 
    SCHEDULES.PRODUCT              = STATUS.PRODUCT          AND 
    SCHEDULES.IDSTRING             = STATUS.IDSTRING         AND 
    SCHEDULES.RECEIVER       = 'ADMILSONDAMASCENO'     AND
    SCHEDULES.SCHEDULING < GETDATE()                   AND
    SCHEDULES.IDSTRING IN (
        SELECT DISTINCT IDSTRING  FROM DEBTS_BBRASIL WHERE
        DEBITOS_BBRASIL.COMPANY        = SCHEDULES.COMPANY        AND
        DEBITOS_BBRASIL.BANK           = SCHEDULES.BANK           AND
        DEBITOS_BBRASIL.PRODUCT        = SCHEDULES.PRODUCT        AND
        DEBITOS_BBRASIL.IDSTRING       = SCHEDULES.IDSTRING       AND
        DEBITOS_BBRASIL.STATUS         <> 2
)
ORDER BY SCHEDULES.SCHEDULING DESC

以下是linq对sql的尝试:

 from sched in SCHEDULES
    join status in STATUS
      on new { sched.IDSTRING, sched.COMPANY, sched.BANK, sched.PRODUCT } 
      equals new { status.IDSTRING, status.COMPANY, status.BANK, status.PRODUCT } 
    into schedStats
    from ss in schedStats
    join debt in DEBITOS_BBRASILs
      on new { ss.IDSTRING, ss.COMPANY, ss.BANK, ss.PRODUCT }
      equals new { debt.IDSTRING, debt.COMPANY, debT.BANK, debt.PRODUCT }
    where sched.RECEIVER.Equals("ADMILSONDAMASCENO") && 
                         sched.SCHEDULING <= DateTime.Now && debt.STATUS != 2
    select new ScheduledStatus
    {
      //Lots of properties here
    };

然而,上面的代码产生Cross-Join然后产生Inner-Join,我肯定会复制一些结果。在SqlServer上测试第一个代码会产生189个结果,而我的linq到sql代码会产生546个结果。我不知道如何将相同的sql代码重现为linq to sql code。

我在linqPad上测试过它只是为了确定。

2 个答案:

答案 0 :(得分:1)

经过大量的“谷歌搜索”后找到了答案。我需要一个子查询来执行另一个表的搜索,而不是另一个表。使用linq to sql方法Any就可以了。这里the post对我帮助最大。

这是翻译我的TSQL代码的linq to sql代码:

    from sched in SCHEDULES
        join status in STATUS
          on new { sched.IDSTRING, sched.COMPANY, sched.BANK, sched.PRODUCT } 
          equals new { status.IDSTRING, status.COMPANY, status.BANK, status.PRODUCT } 
        where sched.RECEIVER.Equals("ADMILSONDAMASCENO") && 
              sched.SCHEDULING <= DateTime.Now && DEBITOS_BBRASILs.Any(dbb=> 
                    dbb.IDSTRING.Equals(sched.IDSTRING) 
                     && dbb.COMPANY.Equals(sched.COMPANY) 
                     && dbb.BANK.Equals(sched.BANK) 
                     && dbb.PRODUCT.Equals(sched.PRODUCT)
                     && dbb.STATUS != 2)
        select new ScheduledStatus
        {
         //Lots of properties here
         };

答案 1 :(得分:1)

使用LINQ to SQL时,通常不应使用显式连接。如果已设置正确的关系,则应具有可以使用的导航属性。有了这些,查询将类似于:

from sched in SCHEDULES
where sched.status.debt != 2;

如果数据库中有外键,则在设计器表面上删除两个表时,SqlMetal.exe或OR设计器会自动生成导航属性。表格之间的关系将用一条线显示(见下面的例子)。

Sample navigation properties