c# - Entity Framework - 无法让 LEFT OUTER join 工作

标签 c# .net entity-framework entity-framework-4.1

请参阅下面的 2 个版本的代码和它生成的 SQL。我想加载首选项,但我也只想带上我的用户首选项,因此我使用 WHERE 子句。但是一旦我把它放进去——我就不再得到 OUTER join 了。为什么?

var query = from p in context.Preferences
                            join up in context.UserPreferences on p.PreferenceKey equals up.PreferenceKey into outer
                            from up in outer.DefaultIfEmpty()
                            select new MobileRESTEntities.UserPreference
                            {
                                CreatedOn = (up == null) ? p.CreatedOn : up.CreatedOn,
                                UpdatedOn = (up == null) ? p.CreatedOn : (up.UpdatedOn ?? up.CreatedOn),
                                PreferenceId = p.PreferenceId,
                                Value = (up == null) ? p.ValueDefault : up.Value,
                            };

哪里:

var query = from p in context.Preferences
                            join up in context.UserPreferences on p.PreferenceKey equals up.PreferenceKey into outer
                            from up in outer.DefaultIfEmpty()
                            where up.UserKey.Equals((int)user.ProviderUserKey)
                            &&
                            (
                            (up == null)
                            ||
                            ((up.UpdatedOn > lastSyncOn && up.UpdatedOn != null) || (up.CreatedOn > lastSyncOn))
                            )
                            select new MobileRESTEntities.UserPreference
                            {
                                CreatedOn = (up == null) ? p.CreatedOn : up.CreatedOn,
                                UpdatedOn = (up == null) ? p.CreatedOn : (up.UpdatedOn ?? up.CreatedOn),
                                PreferenceId = p.PreferenceId,
                                Value = (up == null) ? p.ValueDefault : up.Value,
                            };

没有 WHERE - 好

SELECT 
[Extent1].[PreferenceKey] AS [PreferenceKey], 
CASE WHEN ([Extent2].[UserPreferenceKey] IS NULL) THEN [Extent1].[CreatedOn] ELSE [Extent2].[CreatedOn] END AS [C1], 
CASE WHEN ([Extent2].[UserPreferenceKey] IS NULL) THEN [Extent1].[CreatedOn] WHEN ([Extent2].[UpdatedOn] IS NULL) THEN [Extent2].[CreatedOn] ELSE [Extent2].[UpdatedOn] END AS [C2], 
[Extent1].[PreferenceId] AS [PreferenceId], 
CASE WHEN ([Extent2].[UserPreferenceKey] IS NULL) THEN [Extent1].[ValueDefault] ELSE [Extent2].[Value] END AS [C3]
FROM  [dbo].[MBLPreference] AS [Extent1]
LEFT OUTER JOIN [dbo].[MBLUserPreference] AS [Extent2] ON [Extent1].[PreferenceKey] = [Extent2].[PreferenceKey]

使用 WHERE - 错误 - 没有 OUTER JOIN

exec sp_executesql N'SELECT 
[Extent1].[PreferenceKey] AS [PreferenceKey], 
[Extent2].[CreatedOn] AS [CreatedOn], 
CASE WHEN ([Extent2].[UpdatedOn] IS NULL) THEN [Extent2].[CreatedOn] ELSE [Extent2].[UpdatedOn] END AS [C1], 
[Extent1].[PreferenceId] AS [PreferenceId], 
[Extent2].[Value] AS [Value]
FROM  [dbo].[MBLPreference] AS [Extent1]
INNER JOIN [dbo].[MBLUserPreference] AS [Extent2] ON [Extent1].[PreferenceKey] = [Extent2].[PreferenceKey]
WHERE ([Extent2].[UserKey] = @p__linq__0) AND ((1 = 0) OR (([Extent2].[UpdatedOn] > @p__linq__1) AND ([Extent2].[UpdatedOn] IS NOT NULL)) OR ([Extent2].[CreatedOn] > @p__linq__2))',N'@p__linq__0 int,@p__linq__1 datetime2(7),@p__linq__2 datetime2(7)',@p__linq__0=15,@p__linq__1='0001-01-01 00:00:00',@p__linq__2='0001-01-01 00:00:00'

编辑

是的,WHERE 不会按原样工作,但我的 SQL 应该类似于:

SELECT P.*
FROM dbo.MBLPreference P
LEFT OUTER JOIN dbo.MBLUserPreference UP ON P.PreferenceKey = UP.PreferenceKey
AND UP.UserKey = 8 AND UP.CreatedOn > '1-1-1'

我应该如何编写 LINQ 来实现这一点?

回答

这就是我需要做的(将条件移动到 join 本身)

var query = from p in context.Preferences
                            join up in context.UserPreferences
                            .Where(x => 
                                x.UserKey.Equals((int)user.ProviderUserKey)
                                &&
                                ((x.UpdatedOn > lastSyncOn && x.UpdatedOn != null) || (x.CreatedOn > lastSyncOn))
                                ) 
                            on p.PreferenceKey equals up.PreferenceKey into outer
                            from up in outer.DefaultIfEmpty() 
                            select new MobileRESTEntities.UserPreference
                            {
                                CreatedOn = (up == null) ? p.CreatedOn : up.CreatedOn,
                                UpdatedOn = (up == null) ? p.CreatedOn : (up.UpdatedOn ?? up.CreatedOn),
                                PreferenceId = p.PreferenceId,
                                Value = (up == null) ? p.ValueDefault : up.Value,
                            };

最佳答案

我不确定你想要达到什么目的,但我相信你需要在 where 中移动条件向上:
from p in context.Preferences<br/> join up in context.UserPreferences.Where(x=>x.UserKey ==user.ProviderUserKey &&<br/> (// your other conditions)<br/> )<br/> into outer ....

关于c# - Entity Framework - 无法让 LEFT OUTER join 工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6618776/

相关文章:

c# - Entity Framework 按日期分组并返回新类

sql-server - 如何将存储函数添加到 Entity Framework

entity-framework - 如何使用 Entity Framework 将存储过程的结果映射到具有不同命名参数的实体

c# - Entity Framework 未修改身份列

javascript - jQuery 用户界面 : Uncaught TypeError: Cannot read property 'nodeType' of undefined

c# - 使用 WebBrowser 登录网站后使用 WebClient 下载文件

c# - 使用windows服务和c#检测USB驱动器插入和移除

c# - 如果 Html 文件没有结尾 "/tr"标记或 "/td"标记,则 HTML Agility Pack 无法完美读取该信息

C# 在使用 TimeSpan 时遇到了麻烦。将正常运行时间秒数转换为天/小时

c# - 为什么在 owin 实现后,swagger 不起作用?