2009-11-20 68 views
0

我有以下在SSMS中正常工作的查询。使用LinqPad(C#),但实在令人费解与左外接替林在LinqToSql加入:通过内部连接和2个左侧连接(带子查询)的SQL到Linq转换

SELECT DISTINCT 
    A.LocID, 
    V1.PrfValue AS pID, 
    V2.PrfValue AS sID, 
    D.DivisionManager, 
    A.IsApproved, 
    A.DateCreated 
FROM   
    dbo.Locations AS A 
INNER JOIN 
    dbo.Divisions AS D 
    ON A.DivisionID = D.DivisionID 
LEFT OUTER JOIN 
    dbo.ValuesInLocations AS V1 
    ON A.LocID = V1.LocID 
    AND 
    V1.PrfID IN (SELECT 
      PrfID 
       FROM 
      dbo.PrfTag 
      WHERE 
      (LevelTypeID = 1)) 
LEFT OUTER JOIN 
    dbo.ValuesInLocations AS V2 
    ON A.LocID = V2.LocID 
    AND 
    V2.PrfID IN (SELECT 
      PrfID 
      FROM 
      dbo.PrfTag 
      WHERE 
      (LevelTypeID = 2)) 

正如你所看到的,这是不是开始工作最优雅的查询,我同意两个左连接中的子查询都可以改进。不过,你能帮我翻译这个吗?

回答

1

以下是您的查询的2种可能的翻译。我在第一次翻译中使用了3个独立的查询,使其更具可读性。我希望你觉得它们很有用。

var query1 = 
    from prfTag in DataContext.PrfTag 
    where prfTag.LevelTypeID = 1 
    select PrfID; 

var query1 = 
    from prfTag in DataContext.PrfTag 
    where prfTag.LevelTypeID = 2 
    select PrfID; 

var query = (
from A in DataContext.Locations 
join D in DataContext.Divisions 
    on A.DivisionID equals D.DivisionID 
join V1 in DataContext.ValueInLocations 
    on A.LocID equals V1.LocID 
    into VGroup1 
from V1 in VGroup1.DefaultIfEmpty() 
join V2 in DataContext.ValueInLocations 
    on A.LocID equals V2.LocID 
    into VGroup2 
from V2 in VGroup2.DefaultIfEmpty() 
where (V1 == null || (V1 != null && query1.Contains(V1.PrfID))) 
    && (V2 == null || (V2 != null && query2.Contains(V2.PrfID))) 
select new 
{ 
    A.LocID, 
    pID = V1 != null ? V1.PrfValue : "", 
    sID = V2 != null ? V2.PrfValue : "", 
    D.DivisionManager, 
    A.IsApproved, 
    A.DateCreated 
}).Distinct(); 

这里是第二个可能的转换:

var query = (
from A in DataContext.Locations 
join D in DataContext.Divisions 
    on A.DivisionID equals D.DivisionID 
join V1 in DataContext.ValueInLocations 
    on A.LocID equals V1.LocID 
    into VGroup1 
from V1 in VGroup1.DefaultIfEmpty() 
join prfTag1 in DataContext.PrfTag 
    on V1.PrfID equals prfTag1.PrfID 
join V2 in DataContext.ValueInLocations 
    on A.LocID equals V2.LocID 
    into VGroup2 
from V2 in VGroup2.DefaultIfEmpty() 
join prfTag2 in DataContext.PrfTag 
    on V2.PrfID equals prfTag2.PrfID 
select new 
{ 
    A.LocID, 
    pID = V1 != null ? V1.PrfValue : "", 
    sID = V2 != null ? V2.PrfValue : "", 
    D.DivisionManager, 
    A.IsApproved, 
    A.DateCreated 
}).Distinct(); 
+0

感谢üO.Askari!第二个例子就像一个魅力,从我身边做了一些小调整! – Shalan 2009-11-24 14:24:48

+0

很高兴我能帮忙:) – 2009-11-24 16:33:44

0

在LINQ中可能会有一些棘手的方法来做到这一点,但LINQ JOIN对除了内部连接之外的任何事情都是痛苦的。为了可维护性,我不鼓励在这个查询中使用linq。我知道这并不完全回答你的问题,但我不认为你会得到一个你比这个问题更好的答案。