在NHibernate的查询获取“周边”行
-
22-07-2019 - |
题
我要寻找一种方式,给定一个主键和排序顺序NHibernate的查询检索“周边”行?
E.g。我有一个日志条目表,我想以显示与主键4242是按日期顺序进入和前5项以及下列5项(有日期和主键之间没有直接的关系)。这样的查询应该在总返回11行(只要我们不接近任一端)。
在日志条目表可以是巨大的,并检索所有弄明白是不可能的。
有这样的概念,行号,可以从内NHibernate的使用?底层数据库要么将是SQlite的或Microsoft SQL Server。
<强>被修改强>添加样品
想象诸如以下数据:
Id Time
4237 10:00
4238 10:00
1236 10:01
1237 10:01
1238 10:02
4239 10:03
4240 10:04
4241 10:04
4242 10:04 <-- requested "center" row
4243 10:04
4244 10:05
4245 10:06
4246 10:07
4247 10:08
当请求与主键4242项,我们应该得到的行1237,1238和4239至4247.顺序是按时间,同上。
是否有可能以检索在单个查询(其显然可以包括子查询)的条目?时间是一个非唯一列,以便多个条目具有相同的价值,在这个例子中是不可能改变的方式,使得它独一无二的!
的决议解决方案
“有日期和主键之间没有直接的关系”是指,该主密钥不以连续的顺序?
然后,我会做这样的:
Item middleItem = Session.Get(id);
IList<Item> previousFiveItems = Session.CreateCriteria((typeof(Item))
.Add(Expression.Le("Time", middleItem.Time))
.AddOrder(Order.Desc("Time"))
.SetMaxResults(5);
IList<Item> nextFiveItems = Session.CreateCriteria((typeof(Item))
.Add(Expression.Gt("Time", middleItem.Time))
.AddOrder(Order.Asc("Time"))
.SetMaxResults(5);
有是具有若干项具有相同时间的风险。
修改强>
此应该现在的工作。
Item middleItem = Session.Get(id);
IList<Item> previousFiveItems = Session.CreateCriteria((typeof(Item))
.Add(Expression.Le("Time", middleItem.Time)) // less or equal
.Add(Expression.Not(Expression.IdEq(middleItem.id))) // but not the middle
.AddOrder(Order.Desc("Time"))
.SetMaxResults(5);
IList<Item> nextFiveItems = Session.CreateCriteria((typeof(Item))
.Add(Expression.Gt("Time", middleItem.Time)) // greater
.AddOrder(Order.Asc("Time"))
.SetMaxResults(5);
其他提示
此应该是比较容易与NHibernate的标准API:
List<LogEntry> logEntries = session.CreateCriteria(typeof(LogEntry))
.Add(Expression.InG<int>(Projections.Property("Id"), listOfIds))
.AddOrder(Order.Desc("EntryDate"))
.List<LogEntry>();
在这里您listOfIds
只是表示要检索条目的id整数的强类型列表(整数4242-5至4242 + 5)。
当然,你还可以添加Expressions
,让您检索和IDS比4242-5大于小于4242 + 5。
Stefan的解决方案确实有效,但存在更好的方式使用单一选择和嵌套子查询:
ICriteria crit = NHibernateSession.CreateCriteria(typeof(Item));
DetachedCriteria dcMiddleTime =
DetachedCriteria.For(typeof(Item)).SetProjection(Property.ForName("Time"))
.Add(Restrictions.Eq("Id", id));
DetachedCriteria dcAfterTime =
DetachedCriteria.For(typeof(Item)).SetMaxResults(5).SetProjection(Property.ForName("Id"))
.Add(Subqueries.PropertyGt("Time", dcMiddleTime));
DetachedCriteria dcBeforeTime =
DetachedCriteria.For(typeof(Item)).SetMaxResults(5).SetProjection(Property.ForName("Id"))
.Add(Subqueries.PropertyLt("Time", dcMiddleTime));
crit.AddOrder(Order.Asc("Time"));
crit.Add(Restrictions.Eq("Id", id) || Subqueries.PropertyIn("Id", dcAfterTime) ||
Subqueries.PropertyIn("Id", dcBeforeTime));
return crit.List<Item>();
这是NHibernate的2.0语法,但同样适用于地方的限制,而不是使用Expression早期版本的真。
我已经在一个测试程序测试这一点,它可以作为通告
不隶属于 StackOverflow