我要寻找一种方式,给定一个主键和排序顺序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早期版本的真。

我已经在一个测试程序测试这一点,它可以作为通告

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top