首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Entity Framework Core2.0上使用lambda语法在LINQ中实现左外部联接?

问如何在Entity Framework Core2.0上使用lambda语法在LINQ中实现左外部联接?
EN

Stack Overflow用户
提问于 2018-03-29 17:46:07
回答 1查看 16.4K关注 0票数 2

我正在尝试在Linq中针对实体框架核心2.0 DbContext实现一个左外部联接。重要的是要将查询转换为SQL,而不是本地计算。我已经评论了几个StackOverflow解决方案,包括this one,它很好,但没有一个使用EF核心。

我得到的问题是EF Core为DefaultIfEmpty()方法返回以下警告/错误:

The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally

如果不使用DefaultIfEmpty()方法,则使用内连接。我的LINQ查询如下所示:

代码语言:javascript
复制
var join = context.Portfolios
           .Where(p => p.IsActive)
           .GroupJoin(context.BankAccounts, 
                      prt => prt.Id, 
                      bnk => bnk.PortfolioId, 
                      (prt, bnks) => new {Portfolio=prt,Account=bnks.DefaultIfEmpty()})
           .SelectMany(r => r.Accounts.DefaultIfEmpty(),
                       (p, b) => new 
                           {
                               Id = p.Portfolio.Id,
                               BankAccount = b.BankAccountNumber,
                               BankRef = b.BeneficiaryReference,
                               Code = p.Portfolio.Code,
                               Description = p.Portfolio.DisplayName
                           });

有谁知道解决这个问题的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-29 17:58:59

好吧,这是我的错误,基于另一个SO问题中的评论,该问题指出DefaultIfEmpty()是使查询成为外连接所必需的。查看底层SQL,当我删除DefaultIfEmpty()规范时,将向数据库提交一个左连接。我不确定这是否与在内存中执行左连接收集有所不同,但它已经解决了我的问题。

EF Core为该Linq查询生成的SQL如下所示:

代码语言:javascript
复制
SELECT [p].[ID], 
       [bnk].[BankAccountNumber] AS [BankAccount], 
       [bnk].[BeneficiaryReference] AS [BankRef], 
       [p].[Code], 
       [p].[DisplayName] AS [Description]
    FROM [Portfolio] AS [p]
    LEFT JOIN [BankAccount] AS [bnk] ON [p].[ID] = [bnk].[PortfolioId]
WHERE (([p].[IsActive] = 1)))

编辑:找到时间测试这一点,@Ivan Stoev是正确的:如果在EF上下文定义中正确设置了导航属性,EF将生成左连接。在使用EF时,这是一种更好的方法。

公文包的EF导航属性:

代码语言:javascript
复制
public virtual ICollection<BankAccount> BankAccounts { get; set; }

通过导航属性的LINQ查询:

代码语言:javascript
复制
var join = context.Portfolios
                  .Where(p => p.IsActive)
                  .SelectMany(p => p.BankAccounts.DefaultIfEmpty(), (p, b) => new
                                                {
                                                    Id = p.Id,
                                                    BankAccount = b.BankAccountNumber,
                                                    BankRef = b.BeneficiaryReference,
                                                    Code = p.Code,
                                                    Description = p.DisplayName
                                                });

结果SQL代码:

代码语言:javascript
复制
SELECT [p].[ID], [p.BankAccounts].[BankAccountNumber] AS [BankAccount], [p.BankAccounts].[BeneficiaryReference] AS [BankRef], [p].[Code], [p].[DisplayName] AS [Description]
    FROM [core].[Portfolio] AS [p]
    LEFT JOIN [ims].[BankAccount] AS [p.BankAccounts] ON [p].[ID] = [p.BankAccounts].[PortfolioId]
WHERE (([p].[IsActive] = 1))

请注意,从LINQ查询中删除DefaultIfEmpty()会导致内部联接。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49552859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档