0

我有以下查询在 SSMS 中运行良好。我正在使用 LinqPad ( C# ),但在 LinqToSql 中成功使用左外连接真的令人费解:

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))

如您所见,这不是开始工作的最优雅的查询,我同意两个左连接中的子查询可以改进。但是,你能帮我翻译一下吗?

4

2 回答 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();
于 2009-11-23T05:23:58.023 回答
0

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

于 2009-11-20T00:10:56.130 回答