2011-09-20 71 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