2013-08-04 64 views
4

我需要運行一個LINQ查詢,它將返回3行(當前記錄,上一條記錄和下一條相對於當前記錄的記錄,ProductID是我自動生成的標識列。一個聯盟LINQ聲明,但我不知道是否有更好的或完成相同的任務更有效的方式這是正確的方式來選擇給定當前記錄的ID的前一個和下一個記錄?

這裏是我得到:

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, 
}); 

這應該返回3行的產品ID 9 ,ProductID 10,ProductID 11.謝謝!

回答

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, 
}); 

但請注意,這將返回你只需要什麼,如果沒有相應的規定productIDs記錄已經從產品表中刪除。

4

就我個人而言,我會使用這種方法: 它有工作的好處,在範圍中缺少ID。一個勇敢的人假設所有的Ids都被解釋和呈現。

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); 
+2

我不明白。首先,您在ID列上放置一個where子句(僅留下一條記錄),然後您可以訂購併跳過並取。這仍然只會讓你目前...我錯過了什麼? –

+0

這是正確的,因爲我們不能只是假設ID將在範圍內。這是最佳做法。 –

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 (...),查詢執行計劃員可以很好地處理這個問題。

+0

您錯過了方法名稱。它應該是ids.Contains(...):) – TKharaishvili

+0

你說得對:)這已經是凌晨2點了...... –

0

下面是我將如何解決問題 - 避免使用+ 1,-1。

在我的情況下,我試圖顯示前一個/下一個已發佈博客文章。如果下一個/ prev博客帖子是未發佈,則+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)是沒有必要的,如果您的列表已經按順序。

相關問題