1

我有 2 个表:(pob带有一些活动的结果)和names(带有用户数据)。我尝试pob根据他们的最后活动日期从表中选择前 5 名用户。所以我inner join namesand pob,然后根据计算选择前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)如果我像下面这样删除它就可以了。通过“工作”,我的意思是没有例外,但查询结果当然是错误的,但是分组是正确的。

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# 也可以)

4

1 回答 1

1

解决方案

目前还没有解决办法。看起来 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

我在这里发布了一个问题。

Svyatoslav Danyliv 基于我的问题在这里打开了他自己的问题。

于 2017-05-05T16:54:02.603 回答