例如 数据库有2个表
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
输出显示所有Book列和相关InventoryDetails列(包括InventoryDetails.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,而不是InventoryDetail表格中的详细信息:数量
我忘了什么?
答案 0 :(得分: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;
}
答案 1 :(得分: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
答案 2 :(得分: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);
当然,您可以在Where
来电之前根据需要使用Take
和ToDictionary
。您也可以在此之前仅将您需要的属性作为查询进行投影。您需要通过new
关键字将其投影为匿名类型(之前已丢失,因此请再次查看)。
答案 3 :(得分:0)
在LinqPad 4中查询软件Rockstar的答案会产生错误!所以,那不是那样的!
//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 }