2011-09-20 76 views
0

我有以下型號:LINQ到實體 - 一對多的關係 - 需要左外連接,而不是交叉連接

model.mdmx

我需要的所有燈具和預測的名單(如果燈具有一個預測)爲特定用戶。在SQL返回我需要的是如下:

SELECT * FROM Fixture f 
LEFT OUTER JOIN Prediction p ON f.FixtureId = p.FixtureId 
WHERE p.UserID = '06E4D3E0-8365-45BF-9054-3F8534C7AD5E' OR p.UserID IS NULL 

我曾嘗試:

var query = from f in c.Fixtures 
    from p in c.Predictions.Where(pre => pre.UserId == new Guid("06E4D3E0-8365-45BF-9054-3F8534C7AD5E") || pre.UserId == null) 
    select new 
    { 
     FixtureId = f.FixtureId, 
     HomeScore = f.HomeTeamScore, 
     AwayScore = f.AwayTeamScore, 
     PredictionId = p.PredictionId, 
     HomePrediction = p.HomeTeamPrediction, 
     AwayPrediction = p.AwayTeamPrediction 
     }; 

但是,生成(並給出錯誤的結果):

SELECT 
[Extent1].[FixtureId] AS [FixtureId], 
[Extent1].[HomeTeamScore] AS [HomeTeamScore], 
[Extent1].[AwayTeamScore] AS [AwayTeamScore], 
[Extent2].[PredictionId] AS [PredictionId], 
[Extent2].[HomeTeamPrediction] AS [HomeTeamPrediction], 
[Extent2].[AwayTeamPrediction] AS [AwayTeamPrediction] 
FROM [dbo].[Fixture] AS [Extent1] 
CROSS JOIN [dbo].[Prediction] AS [Extent2] 
WHERE cast('06e4d3e0-8365-45bf-9054-3f8534c7ad5e' as uniqueidentifier) = [Extent2].[UserId] 

添加DefaultIfEmpty到第二個'起'像:

var query = from f in c.Fixtures 
    from p in c.Predictions.Where(pre => pre.UserId == new Guid("06E4D3E0-8365-45BF-9054-3F8534C7AD5E") || pre.UserId == null).DefaultIfEmpty() 
    select new 
    { 
     FixtureId = f.FixtureId, 
     HomeScore = f.HomeTeamScore, 
     AwayScore = f.AwayTeamScore, 
     PredictionId = p.PredictionId, 
     HomePrediction = p.HomeTeamPrediction, 
     AwayPrediction = p.AwayTeamPrediction 
    }; 

生成(仍然給出了錯誤的結果):

SELECT 
[Extent1].[FixtureId] AS [FixtureId], 
[Extent1].[HomeTeamScore] AS [HomeTeamScore], 
[Extent1].[AwayTeamScore] AS [AwayTeamScore], 
[Join1].[PredictionId] AS [PredictionId], 
[Join1].[HomeTeamPrediction] AS [HomeTeamPrediction], 
[Join1].[AwayTeamPrediction] AS [AwayTeamPrediction] 
FROM [dbo].[Fixture] AS [Extent1] 
CROSS JOIN (SELECT [Project1].[PredictionId] AS [PredictionId], [Project1].[HomeTeamPrediction] AS [HomeTeamPrediction], [Project1].[AwayTeamPrediction] AS [AwayTeamPrediction] 
FROM (SELECT 1 AS X) AS [SingleRowTable1] 
LEFT OUTER JOIN (SELECT 
    [Extent2].[PredictionId] AS [PredictionId], 
    [Extent2].[UserId] AS [UserId], 
    [Extent2].[HomeTeamPrediction] AS [HomeTeamPrediction], 
    [Extent2].[AwayTeamPrediction] AS [AwayTeamPrediction] 
    FROM [dbo].[Prediction] AS [Extent2] 
    WHERE cast('06e4d3e0-8365-45bf-9054-3f8534c7ad5e' as uniqueidentifier) = [Extent2].[UserId]) AS [Project1] ON 1 = 1) AS [Join1] 

使用現有的關係,-像(這是我要去哪裏錯了,請參閱下面答案):

var query = from f in c.Fixtures 
    from p in c.Predictions 
    where c.Predictions.Any(pre => pre.UserId == new Guid("06E4D3E0-8365-45BF-9054-3F8534C7AD5E") || pre.UserId == null) 
    select new 
    { 
     FixtureId = f.FixtureId, 
     HomeScore = f.HomeTeamScore, 
     AwayScore = f.AwayTeamScore, 
     PredictionId = p.PredictionId, 
     HomePrediction = p.HomeTeamPrediction, 
     AwayPrediction = p.AwayTeamPrediction 
    }; 

生成:

SELECT 
[Extent1].[FixtureId] AS [FixtureId], 
[Extent1].[HomeTeamScore] AS [HomeTeamScore], 
[Extent1].[AwayTeamScore] AS [AwayTeamScore], 
[Extent2].[PredictionId] AS [PredictionId], 
[Extent2].[HomeTeamPrediction] AS [HomeTeamPrediction], 
[Extent2].[AwayTeamPrediction] AS [AwayTeamPrediction] 
FROM [dbo].[Fixture] AS [Extent1] 
CROSS JOIN [dbo].[Prediction] AS [Extent2] 
WHERE EXISTS (SELECT 
    1 AS [C1] 
    FROM [dbo].[Prediction] AS [Extent3] 
    WHERE cast('06e4d3e0-8365-45bf-9054-3f8534c7ad5e' as uniqueidentifier) = [Extent3].[UserId] 
) 

如何生成我需要的查詢?

+0

http://msdn.microsoft.com/en-us/vcsharp/aa336746 –

+0

你把那個'DefaultIfEmpty'放在哪裏?你能向我們展示完整的查詢嗎? –

+0

編輯顯示'DefaultIfEmpty'使用。 – Sprintstar

回答

5

EF已爲您生成導航屬性,因此請繼續使用它們!

而不是

var query = 
    from f in c.Fixtures 
    from p in c.Predictions 
     .Where(pre => pre.UserId == new Guid("06E4D3E0-8365-45BF-9054-3F8534C7AD5E") 
      || pre.UserId == null) 

嘗試

var query = 
    from f in c.Fixtures 
    from p in f.Predictions 
     .Where(pre => pre.UserId == new Guid("06E4D3E0-8365-45BF-9054-3F8534C7AD5E") 
      || pre.UserId == null) 

注意using join and DefaultIfEmpty is often a mistake in EF

+0

是的,我真的想使用現有的關係,但我已經編輯我的問題,以顯示您的建議的結果.. :( – Sprintstar

+0

@Sprintstar不完全。第二個'from'應該是'f.Predictions',而不是' c.Predictions'.c.Predictions'根本不使用**導航屬性**! – AakashM

+0

啊,我明白了!我沒有使用關係,只是另一個來自,因此交叉連接。 – Sprintstar