【问题标题】:Can't make GroupJoin work. NavigationExpandingExpressionVisitor exception无法使 GroupJoin 工作。 NavigationExpandingExpressionVisitor 异常
【发布时间】:2021-01-30 23:00:40
【问题描述】:

这是我第一次使用 GroupJoin。从我所看到的示例中,它的基本形式看起来非常简单,但是当我使用它时,我总是得到一个 NavigationExpandingExpressionVisitor 异常。这里举个例子:

[Table("Users")]
public class WAUser
{
    public int Id { get; set; }
    
    //TODO: Unique key
    [NotNull]
    public string UserUuid { get; set; } 
    
    [DefaultValue(true)]
    public bool NotifyOnlineState { get; set; }
    [DefaultValue(true)]
    public bool NotifyOfflineState { get; set; }
}


public class WASubscription
{
    public int Id { get; set; }
    
    public string PackageIdentifier { get; set; } //Product package indentifier
    
    public DateTime? ExpiresAt { get; set; } //When the subscription or trial expires
    
    public bool Expired { get; set; }
    
    public bool IsTrial { get; set; }
    
    public int PhoneCount { get; set; } //Number of phones this subscriptions supplies
    
    public int UserId { get; set; }
    public WAUser User { get; set; }
}

var userSubscriptions = await dbContext.Users
                .GroupJoin(dbContext.Subscriptions,
                    u => u.Id,
                    s => s.UserId,
                    (u, subscriptions) => new
                    {
                        User = u,
                        Subscriptions = subscriptions
                    })
                .ToListAsync();

抛出的异常:

未处理的异常。 System.InvalidOperationException:处理 LINQ 表达式 'DbSet .GroupJoin( 外部:数据库集, 内部:u => u.Id, outerKeySelector: s => s.UserId, innerKeySelector: (u, 订阅) => new { 用户 = u, 订阅 = 订阅 })' 通过'NavigationExpandingExpressionVisitor' 失败。这可能表示 EF Core 中的错误或限制。看 https://go.microsoft.com/fwlink/?linkid=2101433了解更多详情 信息。

【问题讨论】:

    标签: linq entity-framework-core


    【解决方案1】:

    很高兴你问。

    问题在于 EF Core 团队不(也不想)提供GroupJoin 翻译。在这个 EF Core GitHub 线程 Query: Support GroupJoin when it is final query operator #19930 上查看我的 cmets,并链接了我试图说服他们包含此类支持的讨论(例如,对于他们为支持 LINQ left outer join 模式所做的工作应该非常容易)。所以请去那里投票,否则争论是它“没有价值”。

    话虽如此,在当前的 EF Core 中,要么添加并使用集合导航属性(首选),要么使用相关子查询而不是 GroupJoin,例如替换

    .GroupJoin(dbContext.Subscriptions,
        u => u.Id,
        s => s.UserId,
        (u, subscriptions) => new
        {
            User = u,
            Subscriptions = subscriptions
        })
    

    .Select(u => new
    {
        User = u,
        Subscriptions = dbContext.Subscriptions.Where(s => u.Id == s.UserId) // <--
    })
    

    【讨论】:

    • 1.我认为您错过了子查询中的 ToList() 。 2. 有没有办法以异步方式做到这一点?
    • 我只替换了GroupJoin 部分。其他部分与您的代码相同。
    • 我的意思是 ToList in => Subscriptions = dbContext.Subscriptions.Where(s => u.Id == s.UserId) (子查询)。如果我不这样做,就会抛出异常。
    猜你喜欢
    • 2019-11-20
    • 1970-01-01
    • 2019-10-19
    • 2010-10-08
    • 2014-09-20
    • 1970-01-01
    相关资源
    最近更新 更多