我需要运行一个LINQ查询,该查询将返回3行(当前记录,上一条记录和相对于当前记录的下一条记录.CroductID是我自动生成的标识列。
目前我正在使用Union LINQ语句执行此操作,但我不确定是否有更好或更有效的方法来完成相同的任务。
这是我得到的:
var ProductID = 10;
var Results = (from p in DB.Products
where p.ProductID == ProductID - 1 //Previous record.
select new Product
{
ProductID = p.ProductID,
ProductTitle = p.ProductTitle,
Views = p.Views,
}).Union(from p in DB.Products
where p.ProductID == ProductID //Current record
select new Product
{
ProductID = p.ProductID,
ProductTitle = p.ProductTitle,
Views = p.Views,
}).Union(from p in DB.Products
where p.ProductID == ProductID + 1 //Next record.
select new Product
{
ProductID = p.ProductID,
ProductTitle = p.ProductTitle,
Views = p.Views,
});
这应为ProductID 9,ProductID 10,ProductID 11返回3行。谢谢!
答案 0 :(得分:5)
我个人会使用这种方法: 它具有在范围内缺少ID的地方工作的好处。一个勇敢的人假设所有的ID都被计算和存在。
var currAndNext = Context.Set<TPoco>()
.Where<TPoco>(t=>t.id == id)
.OrderBy(t=>t.id)
.Skip(0)
.Take(2);
var prev = Context.Set<TPoco>()
.Where<TPoco>(t=>t.id == id)
.OrderByDescending(t=>t.id)
.Skip(1)
.Take(1);
答案 1 :(得分:3)
您的方法可以更快地重写:
var ProductID = 10;
var Results = (from p in DB.Products
where p.ProductID >= ProductID - 1 &&
p.ProductID <= ProductID + 1
select new Product
{
ProductID = p.ProductID,
ProductTitle = p.ProductTitle,
Views = p.Views,
});
但请注意,只有在Products表中没有删除与指定productID相对应的记录时,才会返回您需要的内容。
答案 2 :(得分:1)
GwynBleidd提出了一个很好的解决方案,但是你也可以在这种情况下指定一个ID列表:
var ids = new[] {ProductID - 1, ProcuctID, ProductID + 1};
并在where子句
中使用它var Results = from p in DB.Products
where ids.Contains(p.ProductID)
select new Product
{
ProductID = p.ProductID,
ProductTitle = p.ProductTitle,
Views = p.Views,
};
我认为这是多功能的,EF会将其转换为WHERE [ProductID] IN (...)
,查询执行计划程序可以很好地处理它。
答案 3 :(得分:0)
以下是我将如何解决问题 - 避免使用+ 1,-1。
在我的情况下,我试图展示上一个/下一个发布的博客帖子。如果下一个/上一篇博客帖子未发布,则+ 1,-1将无效。更不用说Ids不总是连续的可能性。
在您的情况下,您可能不想展示缺货产品。
var products = db.Products.Where(x => x.Quantity > 0).OrderBy(x => x.ProductId).ToList();
var previous = products.LastOrDefault(x => x.ProductId < id),
var next = products.FirstOrDefault(x => x.ProductId > id)
这将返回上一个和下一个产品,ProductId
最接近您的起始id
。
注意:如果您的列表已经有序,则无需.OrderBy(x => x.ProductId)
。