我有以下查询在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))
正如您所看到的,这不是开始工作的最优雅的查询,我同意左边连接中的子查询可以得到改进。但是,请你帮我翻译一下吗?
答案 0 :(得分: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();
答案 1 :(得分:0)
在LINQ中可能有一些棘手的方法可以做到这一点,但LINQ JOIN对于内连接以外的任何事情都很痛苦。为了可维护性,我不鼓励使用linq进行此查询。我知道这并没有完全回答你的问题,但我认为你不会得到你喜欢的答案,这比那个问题更好。