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

时间:2017-05-02 18:38:11

标签: vb.net linq linq-to-sql linq2db

我有2个表:select * from products left join filters_to_products on products.id = filters_to_products.product_id where filters_to_products.filter_id in (1,2,3,4); (包含一些活动的结果)和pob(包含用户数据)。我尝试根据上一个活动日期从表names中选择前5位用户。所以我内部加入pobnames,然后根据计算出的pob选择前5位用户。

此查询有效:

max(date)

现在我需要将其转换为Linq查询。这是我的尝试,但它不起作用。

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

"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)

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

1 个答案:

答案 0 :(得分: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编译器在生成表达式树时添加了不必要的转换为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