如何在NHibernate中查询每个组中的第一个条目
How to query the first entry in each group in NHibernate
以下代码在 NHibernate 中使用 LINQ returns 与内存中 LINQ 和 EF LINQ 不同的结果。在 NHibernate 中执行此操作的正确方法是什么?如果LINQ版本确实坏了,用QueryOver
就好了。
using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
for (int i = 0; i < 10; ++i)
{
session.Save(new A()
{
X = i % 2,
Y = i / 2,
});
}
transaction.Commit();
}
using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
//=====================================
var expected = session.Query<A>()
.ToList() // <-- copy to memory
.GroupBy(a => a.X)
.Select(g => g.OrderBy(y => y.Y).First())
.ToList();
Console.WriteLine(string.Join(" ", expected.Select(a => a.Id)));
//=====================================
var actual = session.Query<A>()
.GroupBy(a => a.X)
.Select(g => g.OrderBy(y => y.Y).First())
.ToList();
Console.WriteLine(string.Join(" ", actual.Select(a => a.Id)));
}
public class A
{
public int Id { get; set; }
public int X { get; set; } // indexed
public int Y { get; set; } // indexed
}
预期结果
1 2
实际结果
1 1
记录SQL
NHibernate: select (select program_a0_.Id as id1_0_ from "A" program_a0_ order by program_a0_.Y asc limit 1) as col_0_0_ from "A" program_a0_ group by program_a0_.X
完整代码在错误报告中Incorrect result when using GroupBy with First
2019-8-9更新
查询不应使用 ID。我已将其更改为非唯一 属性。如果解决方案只查询一次SQLite.
,我将不胜感激
似乎最新的 NHibernate 5.3 LINQ 提供程序在 Select 中仅支持聚合函数(MIN、MAX、COUNT...)用于“分组依据”查询。分组查询不支持实体 select。
作为一般解决方案,您可以使用以下方法使用子查询重写“分组依据”查询:
var results = session.Query<A>()
.Where(a => a == session.Query<A>() // Subquery on same entity
.Where(sa => sa.X == a.X) // Group BY key is here
.OrderBy(sa => sa.Y) // Order By key is here
.First() // First entry in group
).ToList();
原“分组依据”查询供参考:
var results = session.Query<A>()
.GroupBy(a => a.X)
.Select(g => g.OrderBy(y => y.Y).First())
.ToList();
以下代码在 NHibernate 中使用 LINQ returns 与内存中 LINQ 和 EF LINQ 不同的结果。在 NHibernate 中执行此操作的正确方法是什么?如果LINQ版本确实坏了,用QueryOver
就好了。
using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
for (int i = 0; i < 10; ++i)
{
session.Save(new A()
{
X = i % 2,
Y = i / 2,
});
}
transaction.Commit();
}
using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
//=====================================
var expected = session.Query<A>()
.ToList() // <-- copy to memory
.GroupBy(a => a.X)
.Select(g => g.OrderBy(y => y.Y).First())
.ToList();
Console.WriteLine(string.Join(" ", expected.Select(a => a.Id)));
//=====================================
var actual = session.Query<A>()
.GroupBy(a => a.X)
.Select(g => g.OrderBy(y => y.Y).First())
.ToList();
Console.WriteLine(string.Join(" ", actual.Select(a => a.Id)));
}
public class A
{
public int Id { get; set; }
public int X { get; set; } // indexed
public int Y { get; set; } // indexed
}
预期结果
1 2
实际结果
1 1
记录SQL
NHibernate: select (select program_a0_.Id as id1_0_ from "A" program_a0_ order by program_a0_.Y asc limit 1) as col_0_0_ from "A" program_a0_ group by program_a0_.X
完整代码在错误报告中Incorrect result when using GroupBy with First
2019-8-9更新
查询不应使用 ID。我已将其更改为非唯一 属性。如果解决方案只查询一次SQLite.
,我将不胜感激似乎最新的 NHibernate 5.3 LINQ 提供程序在 Select 中仅支持聚合函数(MIN、MAX、COUNT...)用于“分组依据”查询。分组查询不支持实体 select。
作为一般解决方案,您可以使用以下方法使用子查询重写“分组依据”查询:
var results = session.Query<A>()
.Where(a => a == session.Query<A>() // Subquery on same entity
.Where(sa => sa.X == a.X) // Group BY key is here
.OrderBy(sa => sa.Y) // Order By key is here
.First() // First entry in group
).ToList();
原“分组依据”查询供参考:
var results = session.Query<A>()
.GroupBy(a => a.X)
.Select(g => g.OrderBy(y => y.Y).First())
.ToList();