我有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位用户。所以我内部加入pob
和names
,然后根据计算出的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#也可以)
答案 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语法我们会收到另一个例外。
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
我发布了一个问题here。
根据我的问题,Svyatoslav Danyliv打开了自己的here。