Entity Framework 投影翻译失败GroupBy
Entity Framework Projection translation failure GroupBy
我一直在清理一些实体 LINQ 方法查询,以尝试优化项目中生成的查询,并试图通过 GROUP BY
外键来避免 JOIN
。但是 运行 与 Entity Framework 的意外投影失败。
使用 LINQPAD 7 中的演示数据库,这是原始查询的示例以及我如何尝试优化它。
作品:
Albums
.Select(a => a.Tracks.OrderBy(t => t.Milliseconds).First())
.Select(g => new { g.Name, g.Composer })
.Dump();
运行时异常:
Tracks.GroupBy(t => t.AlbumId)
.Select(g => g.OrderBy(t => t.Milliseconds).First())
.Select(g => new { g.Name, g.Composer })
.Dump();
现在我知道我可以执行以下操作,但它会产生一个非常奇怪的 SQL 查询(连接到自身)并且不像失败的示例那样清晰易读。
Tracks.GroupBy(t => t.AlbumId)
.Select(g => g.OrderBy(t => t.Milliseconds).Select(g => new { g.Name, g.Composer }).First())
.Dump();
谁能解释为什么 Entity Framework 不喜欢 GroupBy
后跟选择和投影?虽然与 table 的类似联接工作正常?
我正在寻找的最佳查询是:
SELECT Name, Composer
FROM (
SELECT Name, Composer, ROW_NUMBER() OVER(PARTITION BY AlbumId ORDER BY Milliseconds) AS row
FROM Track
)
WHERE row <= 1
我注意到,如果您更改查询顺序,则不会发生异常...
改变这个:
Tracks
.GroupBy(t => t.AlbumId)
.Select(g => g.OrderBy(t => t.Milliseconds).First())
.Select(g => new { g.Name, g.Composer })
.Dump();
有了这个:
Tracks
.OrderBy(x => x.Milliseconds)
.GroupBy(x => x.AlbumId)
.Select(x => new {
x.FirstOrDefault().Name,
x.FirstOrDefault().Composer
})
我认为这是因为您试图在组内对列表进行排序,而您应该先对所有结果进行排序然后再进行分组,尽管我不完全确定。这个,如果不是 linq to sql,就可以正常工作。
我一直在清理一些实体 LINQ 方法查询,以尝试优化项目中生成的查询,并试图通过 GROUP BY
外键来避免 JOIN
。但是 运行 与 Entity Framework 的意外投影失败。
使用 LINQPAD 7 中的演示数据库,这是原始查询的示例以及我如何尝试优化它。
作品:
Albums
.Select(a => a.Tracks.OrderBy(t => t.Milliseconds).First())
.Select(g => new { g.Name, g.Composer })
.Dump();
运行时异常:
Tracks.GroupBy(t => t.AlbumId)
.Select(g => g.OrderBy(t => t.Milliseconds).First())
.Select(g => new { g.Name, g.Composer })
.Dump();
现在我知道我可以执行以下操作,但它会产生一个非常奇怪的 SQL 查询(连接到自身)并且不像失败的示例那样清晰易读。
Tracks.GroupBy(t => t.AlbumId)
.Select(g => g.OrderBy(t => t.Milliseconds).Select(g => new { g.Name, g.Composer }).First())
.Dump();
谁能解释为什么 Entity Framework 不喜欢 GroupBy
后跟选择和投影?虽然与 table 的类似联接工作正常?
我正在寻找的最佳查询是:
SELECT Name, Composer
FROM (
SELECT Name, Composer, ROW_NUMBER() OVER(PARTITION BY AlbumId ORDER BY Milliseconds) AS row
FROM Track
)
WHERE row <= 1
我注意到,如果您更改查询顺序,则不会发生异常...
改变这个:
Tracks
.GroupBy(t => t.AlbumId)
.Select(g => g.OrderBy(t => t.Milliseconds).First())
.Select(g => new { g.Name, g.Composer })
.Dump();
有了这个:
Tracks
.OrderBy(x => x.Milliseconds)
.GroupBy(x => x.AlbumId)
.Select(x => new {
x.FirstOrDefault().Name,
x.FirstOrDefault().Composer
})
我认为这是因为您试图在组内对列表进行排序,而您应该先对所有结果进行排序然后再进行分组,尽管我不完全确定。这个,如果不是 linq to sql,就可以正常工作。