2011-08-28 95 views
0

我有一個自參考表「產品」具有下列結構(其中,d =草案和A =準)問題的LINQ查詢

ID ParentID Status Name 
--------------------------- 
1 NULL  A  Foo 
2 1   A  Foo2 
3 NULL  D  Bar 
4 1   D  Foo3 

一排可以是「新」(其中PARENTID ==空)或可以是現有行的版本。所以我們可以從表格看到,「Foo」項目有3個版本,「Bar」只有1個版本。

我需要根據用戶是否只能看到「已批准」項目或是否能夠看到「草稿」來返回每個項目的最新版本。因此,例如

用戶誰可以看到「d」將有:

3 NULL D 
4 1  D 

「最新」行中「富」與「酒吧」。

用戶誰可以看到 「A」 將有:

2 1  A 

即。只有「已批准」版本。

由於提前,

何塞

+0

你的課程是怎樣的?您使用的是LINQ提供程序?你可以有更長的'ParentID'鏈嗎?例如:6的父親是5,5的父親是1。 – svick

+0

是否爲ParentID +狀態唯一? –

+0

類與數據表具有相同的結構。我正在使用linq 2 sql。深度將只有1(所以沒有子行本身會有孩子)。 – jose

回答

0

這裏是LINQ查詢應爲你工作:

bool hasDraftAccess = false; 

var query = DataContext.Records.AsQueryable(); 

if (!hasDraftAccess) { 
    query = query.Where(r => r.Status == 'A'); 
} 

var seriesQuery = query.Select(r => new { Record = r, SeriesID = r.ParentID ?? r.ID }); 
var latestQuery = seriesQuery.GroupBy(s => s.SeriesID).Select(g => g.OrderByDescending(s => s.Record.ID).First()); 
var resultsQuery = latestQuery.Select(s => s.Record); 
var results = resultsQuery.ToArray(); 

這裏發生的事情:

  1. 首先,如果用戶無權訪問,添加WHERE子句以篩選出草稿記錄
  2. 然後添加名爲'SeriesID'的僞列,將所有相關版本分組到該列中。也就是說,讓家長和相關的孩子分組很容易。
  3. 集團的相關記錄,然後從中挑選哪個記錄是最近
  4. 從匿名類型選擇LINQ的實體,以便它是可更新的

我應該注意的是,如果你要改變你的數據的能力模式,你應該考慮添加一個名爲InsertDate的列或類似的東西。現在我假設無論什麼記錄都有最高的ID是最新的。相反,添加DateTime字段並對其進行排序通常會更好。

我很抱歉,這實際上並沒有使用Linq語法 - 我更喜歡流暢的編碼樣式 - 但如果您願意的話,它可以很容易地轉換爲Linq語法。

+0

謝謝 - 這很好。有一件事 - 我不得不做第二次查詢,使用「contains」從數據庫中獲取完整數據(在結果集合中使用ID) - 是否有一步可以完成這一步?謝謝。 – jose

+0

是的,看我更新的答案。 – emfurry

+0

非常感謝。 – jose

-1

完全未經測試 - 但這樣的事情可能會奏效,如果我理解正確的問題。

可以看到批准

context.Table.Where(p => p.Status == "A") 

可以看到批准草案

context.Table.Where(p => p.Status == "D" || (p.Status == "A" && !context.Table.Any(q => q.Status == "D" && q.Parent == p.Parent)))