给定一个日期,在该日期之前查询最后一条记录的最有效方法是什么,任何等于该日期的记录,以及该日期之后的下一条记录。
它应该在功能上等同于这样的查询:
from asset in Assets
where asset.Id == assetId
select new {
Previous = (from a in a.Orders where a.Date < myDate orderby a.Date descending select a).FirstOrDefault(),
Current = (from a in a.Orders where a.Date == myDate select a).SingleOrDefault(),
Next = (from a in a.Orders where a.Date > myDate orderby a.Date select a).FirstOrDefault()
}
按原样,此查询会运行三个查询,并且可能需要通过myDate对数据集进行三次排序才能执行此操作。
一些类似的问题:
答案 0 :(得分:5)
提供“最有效”的查询取决于您的效率是什么意思。
如果您想要对数据库进行单一查询,按日期进行单一排序,最后按日期进行快速查询,那么我建议以下可能是最有效的。 : - )
var orders =
(from a in Assets
where a.Id == assetId
from o in a.Orders
orderby o.Date
select o).ToArray();
var previous = orders.LastOrDefault(o => o.Date < myDate);
var current = orders.SingleOrDefault(o => o.Date == myDate);
var next = orders.FirstOrDefault(o => o.Date > myDate);
这应该查询数据库一次以查找与所需资产Id关联的订单,按日期对它们进行排序,并将它们作为数组返回到内存中。由于这是在内存中,现在看起来非常快速地寻找当前的,先前的&amp;指定日期的下一个记录。
答案 1 :(得分:2)
您的订单表是否有序列ID字段?如果是这样,您可以使用:
from asset in Assets
where asset.Id == assetID
let current = asset.Orders.Where(x => x.Date == myDate).FirstOrDefault()
where current != null
let previous = asset.Orders.Where(x => x.id == current.id - 1).FirstOrDefault()
let next = asset.Orders.Where(x => x.id == current.id + 1).FirstOrDefault()
select new {
Previous = previous,
Current = current,
Next = next
};
如果没有,那么代码就会多一些:
from asset in Assets
where asset.Id == assetID
let current = asset.Orders.Where(x => x.Date == myDate).FirstOrDefault()
where current != null
let previous = asset.Orders.Where(x => x.Date < current.Date).OrderByDescending(x => x.Date).FirstOrDefault()
let next = asset.Orders.Where(x => x.Date > current.Date).OrderBy(x => x.Date).FirstOrDefault()
select new {
Previous = previous,
Current = current,
Next = next
};
应该编译成一个利用子查询的SQL查询。 IE:数据库服务器将执行多个查询,但您的客户端程序只提交一个。
编辑如果您的订单表有连续ID,则另一个想法是:
var sample = (from asset in Assets
where asset.Id == assetID
let current = asset.Orders.Where(x => x.Date == myDate).FirstOrDefault()
where current != null
from order in asset.Orders
where order.Id == current.id - 1
select order)
.Take(3)
.ToArray();
var Previous = sample[0];
var Current = sample[1];
var Next = sample[2];
答案 2 :(得分:1)
其他答案,例如,SkipWhile等非常慢。祝你好运^^
//Current Record
var query
= (from item in db.Employee
where item.UserName.Equals(_username)
select item).SingleOrDefault();
//Next Record
var query
= (from item in db.Employee
where item.UserName.CompareTo(_username) > 0
select item).FirstOrDefault();
//Previous Record
var query
= (from item in db.Employee
where item.UserName.CompareTo(_username) < 0
orderby item.UserName Descending
select item).FirstOrDefault();
答案 3 :(得分:0)
几乎相同,但SQL查询计划可能不同。
var q =
from asset in Assets
where asset.Id == assetID
select new
{
Previous = asset.Orders.where(a => a.Date == asset.Orders.Where(x => x.Date < myDate).Max(x => x.Date)).FirstOrDefault(),
Current = asset.Orders.Where(x => x.Date == myDate).FirstOrDefault(),
Next = asset.Orders.where(a => a.Date == asset.Orders.Where(x => x.Date > myDate).Min(x => x.Date)).FirstOrDefault()
};