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 }