Linq join query
For example DB with 2 Tables
Book [BookId (int), Title (nvarchar), ShowInWebshop (bit)] and
InventoryDetail [InventoryDetailId (int), BookId (int), Quantity (int)]
Execute: SELECT * FROM Books LEFT JOIN InventoryDetails ON books.BookId = InventoryDetails.BookId
The output shows all Book columns and related InventoryDetails columns (including the InventoryDetails.Boo开发者_开发技巧kId column) ..so far so good ... Trying to transform this query into a Linq one (using LinqPad, comparing several examples, common sense, etc.) I compilated the following generic List (because I wanted a present a list)
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
}
This module returns a list of books! Not the one I expected, though! It returns only book details such as Title and ShowOnSite NOT the details from the InventoryDetail table: Quantity
What do I forget?
The result how it works so far ...
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;
}
You need to select from both tables, e.g.
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
You're getting books because you specified that in your Join
statement with the final selector of => b
. You want to select both, so use this:
var query = webshopDB.Books.Join(webshopDB.InventoryDetails,
b => b.BookId, i => i.BookId,
(b, i) => new { Book = b, InventoryDetail = i });
Then when you iterate over the results you can use:
foreach (var item in query)
{
Console.WriteLine(item.Book.SomeProperty);
Console.WriteLine(item.InventoryDetail.SomeProperty);
}
The other problem with your method is that the return type is a List<Book>
. So the above won't work since a Book
class is separate from an InventoryDetail
class. You need to setup a new class to encompass both, or use a Tuple<Book, InventoryDetail>
if using .NET 4.0.
To return a particular property you could modify the statement to:
var query = webshopDB.Books.Join(webshopDB.InventoryDetails,
b => b.BookId, i => i.BookId,
(b, i) => new { b.BookId, i.Quantity });
Again, you need an appropriate return type if you're returning a List<T>
.
EDIT: to get a Dictionary<Book, InventoryDetail>
you could use the earlier query as follows:
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);
Of course you can use the Where
and Take
as necessary before the ToDictionary
call. You can also project just the properties you need as the query just before this one. You need to project it into an anonymous type via the new
keyword (it was missing earlier so take another look at it).
Quering the answer of SoftwareRockstar in LinqPad4 generates errors! So, that's not the way!
//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 }
精彩评论