我已经构建了一个HQL来使用CreateQuery查询某些实体,并且我尝试使用QueryOver将其转换为lambda表达式。
查询会在Negocio
和Latitude
范围内查找Longitude
,并按用户与Negocio
之间的距离对其进行排序。我想将它转换为lambda表达式,因为它更容易维护,但我仍然按部分顺序排列。
这些是我拥有的实体。我已经省略了在这种情况下不相关的内容。
public class Negocio
{
public Endereco Endereco {get; set;}
}
public class Endereco
{
public GeoCoordenada GeoCoordenada {get; set;}
}
public class GeoCoordenada
{
public double Latitude {get; set;}
public double Longitude {get; set;}
}
这是执行魔术的查询:
query = _session.CreateQuery(@"select distinct(n),
SQRT(SQUARE(e.GeoCoordenada.Latitude - :lat) + SQUARE(e.GeoCoordenada.Longitude - :lon))
from Negocio n inner join n.Endereco as e where
(e.GeoCoordenada.Latitude between (:minLat) and (:maxLat)) and
(e.GeoCoordenada.Longitude between (:minLon) and (:maxLon))
order by SQRT(SQUARE(e.GeoCoordenada.Latitude - :lat) +
SQUARE(e.GeoCoordenada.Longitude - :lon))");`
query.SetParameter("minLat", -90); // random values just
query.SetParameter("maxLat", 90); // for testing
query.SetParameter("minLon", -180);
query.SetParameter("maxLon", 180);
query.SetParameter("lat", 25);
query.SetParameter("lon", 25);
这就是我现在所做的:
var query = _session.QueryOver<Negocio>()
.JoinQueryOver(x => x.Endereco)
.WhereRestrictionOn(x => x.GeoCoordenada.Latitude).IsBetween(-90).And(90)
.AndRestrictionOn(x => x.GeoCoordenada.Longitude).IsBetween(-180).And(180)
重要提示:我无法在调用List()后对其进行排序,因为在skip()
和take()
的查询末尾会添加分页功能所以,一次查询所有结果毫无意义
关于如何实现这种排序的任何想法?
答案 0 :(得分:0)
您可以使用ArithmeticOperatorProjection
,这是为NHibernate编写的小扩展程序:http://savale.blogspot.ru/2011/04/nhibernate-and-missing.html
您的查询将如下所示:
_session.QueryOver<Negocio>()
.JoinQueryOver(x => x.Endereco)
.JoinQueryOver(x => x.GeoCoordenada)
.WhereRestrictionOn(x => x.Latitude).IsBetween(-90).And(90)
.AndRestrictionOn(x => x.Longitude).IsBetween(-180).And(180)
.OrderBy(
new ArithmeticOperatorProjection(
"+",
NHibernateUtil.Decimal,
new ArithmeticOperatorProjection(
"*",
NHibernateUtil.Decimal,
new ArithmeticOperatorProjection("-", NHibernateUtil.Decimal, Projections.Property<GeoCoordenada>(x => x.Longitude), Projections.Constant(25m)),
new ArithmeticOperatorProjection("-", NHibernateUtil.Decimal, Projections.Property<GeoCoordenada>(x => x.Longitude), Projections.Constant(25m))
),
new ArithmeticOperatorProjection(
"*",
NHibernateUtil.Decimal,
new ArithmeticOperatorProjection("-", NHibernateUtil.Decimal, Projections.Property<GeoCoordenada>(x => x.Latitude), Projections.Constant(25m)),
new ArithmeticOperatorProjection("-", NHibernateUtil.Decimal, Projections.Property<GeoCoordenada>(x => x.Latitude), Projections.Constant(25m))
)
)
.List();
可以通过添加自定义SQRT
和SQUARE
投影来进一步改善这一点。