2017-02-12 102 views
0

基本思路從兩個表中選擇*成僞碼兩個單獨列出

Select(a, b) => new Tuple<List<Item1>, List<Item2>>(a, b)

我試圖做到這一點:

  • 一個查詢到數據庫
  • 顯然是在利用linq(查詢或方法語法)

這裏是t WO類涉及

public class Bundle 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public HashSet<Inventory> Inventories { get; set; } 
} 

public class Inventory 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public int Stock { get; set; } 
} 

現在所有我能想到的是

using (var context = new MyEntities()) 
{ 
    return new Tuple<IEnumerable<Inventory>, IEnumerable<Bundle>>(context.Inventories.OrderBy(a => a.Stock).ToList() 
     , context.Bundles.Include(b => b.Inventories).OrderBy(c => c.Name).ToList()); 
} 

然而,這擊中了兩次數據庫。

我知道UNION用於組合來自2個不同查詢的結果集,但這兩個查詢必須具有相同的列數,所以我認爲在選擇相同數據時最好使用它。

如何從兩個不同的表中選擇數據到兩個單獨的列表中,只有一個命中db?

+2

爲希望只打一次數據庫有什麼特別的原因嗎? – Sam

+0

只是爲了儘量減少執行的查詢的數量 – Adrian

回答

1

如果您擔心性能,我認爲減少查詢量是不行的。事實上,如果你需要細粒度優化,LINQ也不是最合適的工具。這就是說,你可以讓兩個不同的對象匹配相同的接口/列,爲其他類型中缺少的對象填充虛擬屬性。理論上這應該轉換爲包含所有列的SQL union

var union = context.Inventories 
    .Select(i => new { i.Id, i.Name, i.Stock, Inventories=null }) 
    .Concat(context.Bundles.Select(b => new { b.Id, b.Name, Stock=0, b.Inventories)); 

注意,在這種情況下Concat優於的Union,因爲它不會改變你行的順序,並允許重複行。

0

你所要求的是不可能的。 如果您試圖獲得兩個不同的結果,您需要按數據庫兩次,每個結果集一次。你可以做一個外連接,但是這會讓你的結果集大於它應該的大小,並且根據你想打一次數據庫的事實來判斷,你關心的是性能。 另外,如果性能問題,我不會首先使用Linq。

+0

我同意你在linq點。這個項目只是面試的一部分,所以我試圖預見我可能遇到的任何「陷阱」。這很奇怪,但我一直認爲會有辦法一次完成這個任務。 – Adrian

+1

Ahhh面試問題通常沒有意義:) – albattran

2

如果你想要兩個結果集,你可以通過拋出兩個查詢來完成。這可以在沒有問題的單個數據庫調用中完成,但它不會神奇地劃分爲兩組對象,因爲您感興趣。

實際上,詢問多個問題並獲取多個結果集是當建立連接的成本(實例化成本或等待時間成本等)足以證明它是非常普遍的時候。我自己在一個存儲過程中完成了它,在一個查詢中要求頁面需要的所有內容。

但是,如果性能是關鍵問題,緩存也很常見。而且,如果這些列表是下拉列表,或者列表請求的列表很小,並且列表不會經常更改,那麼甚至可以在應用程序啓動時將其放入內存中,並將其設置在Web服務器上,以便您不會使數據庫旅行。

我不喜歡的LINQ to SQL的,因爲它創造了DBA的一塌糊塗,但你可以做這樣的事情(只是一個例子,任何方法在那裏你可以鏈命令將工作):

var connString = "{conn string here}"; 
var commandString = "select * from tableA; select * from tableB"; 
var conn = new SqlConnection(connString); 
var command = new SqlCommand(commandString, conn); 
try { 
    conn.Open(); 
    var result = command.Execute(); 
    // work with results here 
} 
finally { 
    conn.Dispose(); 
} 

我還沒有填寫所有的細節,但你可以用任意數量的命令來完成。再一次,如果信息沒有改變,考慮一次命中並保存在內存中(通過編程緩存)或使用其他類型的緩存機制。

+0

Gregory,我非常感謝你的深思熟慮的迴應,但是我必須將Sam的回答標記爲正確,因爲他使用linq展示了一個可能的解決方案。不過,我贊成你的答案。 – Adrian

+0

@Adrian - 沒問題。我與LINQ to SQL的問題是DBA的噩夢。對於一個小項目來說不錯,但在企業環境中不太好。我不反對LINQ本身,因爲我發現它是一種梳理對象的好方法。有趣的是,LINQ to SQL的編寫很大程度上是由於SQL Server 2005(實體框架1.0)的延遲以及演示如何在啓動Visual Studio 2005的15分鐘內構建網站的演示。 –