5

我需要运行一个 LINQ 查询,它将返回 3 行(当前记录、上一条记录和相对于当前记录的下一条记录。ProductID 是我自动生成的标识列。

目前我正在使用 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 行。谢谢!

4

5 回答 5

6

我个人会使用这种方法:它的好处是可以在范围内缺少 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);
于 2013-08-04T23:56:36.960 回答
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 对应的记录时,这才会返回您需要的内容。

于 2013-08-04T23:48:33.187 回答
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 (...),查询执行计划程序可以很好地处理它。

于 2013-08-04T23:56:44.117 回答
1

以下是我解决问题的方法——避免使用 +1,-1。

就我而言,我试图展示上一个/下一个发布的博客文章。如果下一篇/上一篇博文未发布,+1,-1 将不起作用。更不用说 Id 并不总是连续的可能性。

在您的情况下,您可能不想显示缺货产品。

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)如果您的列表已经有序,则不需要。

于 2017-10-10T14:12:58.753 回答
0

phil soady 发布了一个非常好的解决方案。

作为对它的一个小改动,我使用 .Where<TPoco>(t=>t.id <= id).Where<TPoco>(t=>t.id >= id)使其工作。

于 2021-08-19T12:56:17.070 回答