【发布时间】:2012-11-20 07:59:53
【问题描述】:
拥有三个表(Item、Purchase、PurchaseItem),我正在尝试编写一个 linq 查询来查找一个项目包含多少有效购买。
在标准 SQL 中,我会使用带有计数的子查询,但我似乎无法获得 linq 查询来执行此操作。
SQL:
select i.name,
InTrade = (select count(*) from Purchase p join PurchaseItem pi on p.id = pi.PurchaseId where p.Isvalid = 1 and pi.ItemId = i.Id)
from Item i
林克:
from i in Items select new
{
i.Name,
InTrade = from pi in PurchaseItems where pi.ItemId == i.ID
select new
{
pi,
Purchase = from p in Purchases where p.ID == pi.PurchaseId
select new { p }
}
}
这里我试图在一个查询中检索我的所有数据,我可能需要另一个查询才能真正得到我想要的。使用这种方法,我可能会走上一条麻烦的道路,所以也许有人可以阐明在 linq 中实现这一目标的“最佳实践”。
我为这个例子准备了一些测试数据:
if exists (select * from sysobjects where name = 'PurchaseItem') drop table PurchaseItem
if exists (select * from sysobjects where name = 'Item') drop table Item
if exists (select * from sysobjects where name = 'Purchase') drop table Purchase
go
create table Item
(
ID int not null primary key,
Name nvarchar(30) not null
)
create table Purchase
(
ID int not null primary key,
Name nvarchar(30) not null,
ConfirmedDate datetime,
Isvalid bit not null
)
create table PurchaseItem
(
ID int not null primary key,
PurchaseId int null references Purchase(ID),
ItemId int null references Item(ID)
)
insert Item values (1, 'Bread')
insert Item values (2, 'Beer')
insert Item values (3, 'Wine')
insert Item values (4, 'Milk')
insert Item values (5, 'Apple')
insert Item values (6, 'Steak')
insert Item values (7, 'Hamburger')
insert Item values (8, 'Vinegar')
insert Purchase values (1, 'Purchase 1', null, 1)
insert Purchase values (2, 'Purchase 2', null, 0)
insert Purchase values (3, 'Purchase 3', '2008-1-7', 1)
insert PurchaseItem values (1, 1, 1)
insert PurchaseItem values (2, 1, 2)
insert PurchaseItem values (3, 1, 3)
insert PurchaseItem values (4, 1, 4)
insert PurchaseItem values (5, 1, 5)
insert PurchaseItem values (6, 1, 6)
insert PurchaseItem values (7, 2, 2)
insert PurchaseItem values (8, 3, 2)
insert PurchaseItem values (9, 3, 1)
insert PurchaseItem values (10, 3, 5)
【问题讨论】:
-
您的购买是双向映射的吗?意思是,PurchaseItem 有一个 List
作为属性。如果是这种情况,您可能可以简化很多。 -
不,它目前没有像那样映射。一种方法可能是对我的第一个实体执行 .ToList() ,然后对每个实体执行一个并逐个实体填充它。虽然我希望尽可能长时间地让所有内容都可以查询
-
迭代可能不是一个好主意,因为您将向数据库发出一堆查询,而这可以用一个来完成。如果你有双向关系,你就不必通过 id 和类似的东西加入。有几种不同的方法,我会看看是否可以发布一些供您尝试。然后您可以跟踪 SQL 以确保它只发出一个查询。
-
是的,你可能是对的,迭代不是最好的方法。我已经开始从“子查询”重写 linq 以加入。也许这会更容易。
-
我刚刚发布了一些您可以尝试的不同替代方案。我通常尽量避免手动连接,因为这是 ORM 的全部目的,通过让实体具有真实关系来避免手动工作。
标签: linq linq-to-sql