2010-11-14 95 views
1

例如 DB用2個表LINQ的連接查詢

Book [BookId (int), Title (nvarchar), ShowInWebshop (bit)] and 
InventoryDetail [InventoryDetailId (int), BookId (int), Quantity (int)] 

執行:SELECT * FROM Books LEFT JOIN InventoryDetails ON books.BookId = InventoryDetails.BookId

輸出顯示所有預訂列和相關InventoryDe​​tails列(包括InventoryDe​​tails.BookId列) ..所以遠所以好... 試圖將這個查詢轉換成Linq的一個(使用LinqPad,比較幾個例子,常識等)我編譯了以下通用列表(因爲我想要一個列表)

private List<Book> Books(int count){ 
    var books = webshopDB.Books 
     .Join<Book, InventoryDetail, int, Book>(webshopDB.InventoryDetails, 
      b => b.BookId, 
      i => i.BookId, 
      (b, i) => b) 
     .Where(b => b.ShowInWebshop == true) 
     .Take(count) 
     .ToList(); 
    return books 
} 

此模塊返回書籍列表!雖然不是我期望的那個!它僅返回書名的詳細信息,例如Title和ShowOnSite,而不是InventoryDe​​tail表中的詳細信息:數量

我該怎麼忘記?

回答

1

結果它是如何工作至今...

public ActionResult Index() 
{     
    // This return a list of tuples {(WebshopDB.Models.Book, WebshopDB.Models.InventoryDetail)} 
    // Each tuple containing two items: 
    // > Item1 {WebshopDB.Models.Book} 
    // > Item2 {WebshopDB.Models.InventoryDetail} 
    var tuple_books = ListOfTuples_BookInventoryDetail(5); 
    ... 
    // next step(s) 
    // add a ViewModel viewmodel 
    // ... 
    return (viewmodel); 
} 

private List<Tuple<Book, InventoryDetail>> ListOfTuples_BookInventoryDetail(int count) 
{ 
    var list_of_tuples = new List<Tuple<Book, InventoryDetail>>(); 

    var showbooks = webshopDB.Books 
    .Join(webshopDB.InventoryDetails, b => b.BookId, i => i.BookId, (b, i) => new { b = b, i = i }) 
    .Where(o => (o.b.ShowInWebshop == true)) 
    .Where(o => o.b.BookThumbUrl.Contains(".jpg")) 
    .OrderByDescending(o => o.b.OrderDetails.Count()) 
    .Take(count);   

    foreach (var item in showbooks) 
    { 
    list_of_tuples.Add(Tuple.Create<Book, InventoryDetail>((item.b), (item.i))); 
    } 
    return list_of_tuples; 
} 
0

您需要從兩個表中選擇,例如,

from b in webshop.Books 
from i in webshopDB.InventoryDetails 
where i.BookId = b.BookId 
select b.BookId, b.Title, b.ShowInWebshop, i.InventoryDetailId, i.Quantity 
+0

查詢您的答案會產生錯誤!下面的作品(在LinqPad4中):從b在Books 中從我在InventoryDe​​tails中b.BookId == i.BookId其中b.ShowInWebshop == true選擇新的{b.Title,i.Quantity} – KWHJ 2010-11-16 16:59:30

+0

是的,這是正確的。對不起,疏忽了;當我發佈答案時,我沒有LinqPad或其他開發工具。 – SoftwareRockstar 2010-11-17 04:48:00

0

,因爲你指定的,在你的Join語句的=> b最後選擇你得到的書籍。你要選擇兩個,所以用這個:

var query = webshopDB.Books.Join(webshopDB.InventoryDetails, 
        b => b.BookId, i => i.BookId, 
        (b, i) => new { Book = b, InventoryDetail = i }); 

然後,當您遍歷結果,你可以使用:

foreach (var item in query) 
{ 
    Console.WriteLine(item.Book.SomeProperty); 
    Console.WriteLine(item.InventoryDetail.SomeProperty); 
} 

的另外一個問題你的方法是,返回類型是List<Book>。所以上述不起作用,因爲Book班級與InventoryDetail班級是分開的。您需要設置一個新的類來包含這兩個類,或者如果使用.NET 4.0,則使用Tuple<Book, InventoryDetail>

要返回您可以修改語句特定屬性:

var query = webshopDB.Books.Join(webshopDB.InventoryDetails, 
        b => b.BookId, i => i.BookId, 
        (b, i) => new { b.BookId, i.Quantity }); 

同樣,你如果你返回一個List<T>需要一個合適的返回類型。

編輯:獲得Dictionary<Book, InventoryDetail>如下,你可以使用較早查詢:

var query = webshopDB.Books.Join(webshopDB.InventoryDetails, 
        b => b.BookId, i => i.BookId, 
        (b, i) => new { Book = b, InventoryDetail = i }) 
       .ToDictionary(o => o.Book, o => o.InventoryDetail); 

當然你也可以使用必要的WhereTakeToDictionary電話。您也可以在此之前將您需要的屬性作爲查詢進行投影。您需要通過new關鍵字將它投影到匿名類型中(它以前丟失了,所以再看看它)。

+0

@ user507458:我之前錯過了'new'關鍵字。看看我上面編輯的ToDictionary解決方案。請記住,只有您擁有唯一的密鑰時,這纔會起作用。你也需要將你的返回類型改爲'Dictionary '或者你決定返回的任何類型。 – 2010-11-14 22:34:16

+0

嗨Ahmad Mageed, 同時,我只設法通過使用方法Tuple.Create (book,inventorydetail):)返回一個Tuple類型。 但是,它只返回數據庫中的最後一條記錄。所以,我必須弄清楚如何讓所有'book'和'inventorydetail'出來。特別是,如果我想添加一個額外的連接(例如,以及OrderDetail)。 因此,我實現了字典返回類型(THX爲您的親切幫助)。 – KWHJ 2010-11-15 15:42:42

+0

所以問題仍然存在:如何從字典(或Tuple:物品的情況下)獲取對象Book(作爲關鍵字)和對象InventoryDe​​tail(作爲值),並將它們正確存儲到ViewModel中? – KWHJ 2010-11-15 15:43:30

0

Quering SoftwareRockstar的LinqPad4答案生成錯誤!所以,那不是這樣!

//This does works (in LinqPad4)  
from b in webshopDB.Books 
from i in webshopDB.InventoryDetails 
where b.BookId == i.BookId 
where b.ShowInWebshop == true 
select new { b.Title, i.Quantity, b.ShowInWebshop }