Linq2Db / Access - 多个字段的匿名组错误

Linq2Db / Access - error with anonymous group by multiple fields

我有 2 个 table:pob(一些活动的结果)和 names(用户数据)。我尝试根据 activity 的最后 activity 日期从 table pob 中 select 排名前 5 的用户。所以我内部加入 namespob,然后 select 根据计算出的前 5 个用户 max(date)

此查询有效:

SELECT TOP 5
    [u].[id], 
    [u].[name],
    max([p].[date]) As LastDateOfUse,
FROM
    [pob] [p]
INNER JOIN
    [users] [u] 
ON
    [p].[id_name] = [u].[id] 
WHERE
    [p].[date] >= #2017-01-01#
GROUP BY
    [u].[id],
    [u].[name] 
ORDER BY
    max([p].[date]) DESC

现在我需要将其转换为 Linq 查询。这是我的尝试,但没有用。

"Key" is not a member of type "System.Collections.Generic.IEnumerable'1[VB$AnonymousType_2'2[pob,users]]".

Using db = New DbContext() With {.InlineParameters = True}

    Dim query1 = From p In db.pob
                 Join u In db.users On p.id_name Equals u.id
                 Where p.date >= New Date(2017, 1, 1)
                 Group New With {p, u} By pu = New With {Key u.id, Key u.name} Into pg = Group
                 Select New RecentUser With
                 {
                     .id = pu.id,
                     .name = pu.name,
                     .LastDateOfUse = pg.Max(Function(f) f.p.date)
                 }

    query1 = query1.OrderByDescending(Function(f) f.LastDateOfUse).Take(5)

    Return query1.ToList

End Using

如果我像下面那样删除 .LastDateOfUse = pg.Max(Function(f) f.p.Date) 它就可以了。 'works' 我的意思是没有例外,当然查询结果是错误的,但是分组是正确的。

Using db = New DbContext() With {.InlineParameters = True}

    Dim query1 = From p In db.pob
                 Join u In db.users On p.id_name Equals u.id
                 Where p.date >= New Date(2017, 1, 1)
                 Group New With {p, u} By pu = New With {Key u.id, Key u.name} Into pg = Group
                 Select New RecentUser With
                 {
                     .id = pu.id,
                     .name = pu.name
                 }

    Return query1.ToList

End Using

编辑

我也尝试过如下所示的导航属性,但我再次收到相同的错误。

Using db = New DbContext() With {.InlineParameters = True}

    Dim query1 = From p In db.pob
                 Where p.date >= New Date(2017, 1, 1)
                 Group p By pu = New With {Key u.User.id, Key u.User.name} Into pg = Group
                 Select New RecentUser With
                 {
                     .id = pu.id,
                     .name = pu.name
                     .LastDateOfUse = pg.Max(Function(f) f.date)
                 }

    query1 = query1.OrderByDescending(Function(f) f.LastDateOfUse).Take(5)

    Return query1.ToList

End Using

再次,如果我像下面那样删除 .LastDateOfUse = pg.Max(Function(f) f.p.Date),它就会开始工作(正确的分组,错误的整体结果)。

Using db = New DbContext() With {.InlineParameters = True}

    Dim query1 = From p In db.pob
                 Where p.date >= New Date(2017, 1, 1)
                 Group p By pu = New With {Key u.User.id, Key u.User.name} Into pg = Group
                 Select New RecentUser With
                 {
                     .id = pu.id,
                     .name = pu.name
                 }

    Return query1.ToList

End Using

如何将上述 Sql 查询转换为 Linq? (VB.Net 中的最佳答案,但 C# 也可以)

解决方案

目前还没有解决办法。看起来 VB 有错误的 Linq 查询解析器 - 它创建了无法转换为 SQL.

的意外方法链

所以改为

Group By ... Into pg = Group 

我们需要

Group By ... Into LastDateOfUse = p.Max(Function(f) f.date).

请参阅下面的完整查询。

Using db = New DbContext() With {.InlineParameters = True}

    Dim query1 = From p In db.pob
                 Where p.date >= New Date(2017, 1, 1)
                 Group p By pu = New With {Key u.User.id, Key u.User.name} Into LastDateOfUse = p.Max(Function(f) f.date)
                 Select New RecentUser With
                 {
                     .id = pu.id,
                     .name = pu.name
                     .LastDateOfUse = LastDateOfUse
                 }

    Return query1.ToList

End Using

lambda 语法的另一个问题

使用 lambda 语法,我们收到另一个异常。

Dim query = db.pob.
Where(Function(f) f.date >= New Date(2017, 1, 1).
GroupBy(Function(f) New With 
{
   Key .userid= f.user.id,
   Key .username = f.user.name
}).Select(Function(f) New RecentUser With
{
   .id = f.Key.userid,
   .name = f.Key.username,
   .LastDateOfUse = f.Max(Function(g) g.date)
}).ToList

异常

VB.NET 编译器在生成表达式树时添加了不必要的 Convert to IEnumerable。

An unhandled exception of type LinqToDB.Linq.LinqException occurred in linq2db.dll
Convert(f).Select(g => g.Date).Max() cannot be converted to SQL

GitHub

我发布了一个问题 here

Svyatoslav Danyliv 根据我的问题打开了他自己的 here