有了三个表(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 iLinq:
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)发布于 2012-11-20 06:57:18
我认为有几种方法可以实现这一点,只需对数据库进行一次查询。下面是我能想到的两个例子:
使用项目与其购买之间的双向关联:
var resultUsingSubItems = context.PurchaseItems.Select(x => new
{
Item = x,
ValidPurchases = x.Purchases.Count(y => y.IsValid)
});另一种方法是按项目分组:
var resultUsingGrouping = context.Purchases.GroupBy(x => x.Item).Select(
g => new
{
Item = g.Key,
ValidPurchases = g.Count(y => y.IsValid)
});请使用SQL profiler以确保Linq2SQL将其转换为单个SQL查询。
发布于 2012-11-20 07:59:53
您还可以执行以下操作:
var results = from i in db.Items
select new InTradeResult
{
ProductName = i.Name,
InTradeCount = i.PurchaseItems.Count(pi => pi.Purchase.IsValid)
};下面是一个示例控制台应用程序,其中显示了结果:
class Program
{
static void Main(string[] args)
{
using (var db = new Context())
{
var results = from i in db.Items
select new InTradeResult
{
ProductName = i.Name,
InTradeCount = i.PurchaseItems.Count(pi => pi.Purchase.IsValid)
};
foreach (var result in results)
{
System.Console.WriteLine("{0} - {1}", result.InTrade, result.ProductName);
}
System.Console.ReadKey();
}
}
}
public class InTradeResult
{
public string ProductName { get; set; }
public int InTradeCount { get; set; }
}
public class Context : IDisposable
{
public IList<Item> Items { get; set; }
public IList<Purchase> Purchases { get; set; }
public IList<PurchaseItem> PurchaseItems { get; set; }
public Context()
{
Items = new List<Item>();
Items.Add(new Item { ID = 1, Name = "Bread" });
Items.Add(new Item { ID = 2, Name = "Beer" });
Items.Add(new Item { ID = 3, Name = "Wine" });
Items.Add(new Item { ID = 4, Name = "Milk" });
Items.Add(new Item { ID = 5, Name = "Apple" });
Items.Add(new Item { ID = 6, Name = "Steak" });
Items.Add(new Item { ID = 7, Name = "Hamburger" });
Items.Add(new Item { ID = 8, Name = "Vinegar" });
Purchases = new List<Purchase>();
Purchases.Add(new Purchase { ID = 1, Name = "Purchase 1", ConfirmedDate = null, IsValid = true });
Purchases.Add(new Purchase { ID = 2, Name = "Purchase 2", ConfirmedDate = null, IsValid = false });
Purchases.Add(new Purchase { ID = 3, Name = "Purchase 3", ConfirmedDate = null, IsValid = true });
PurchaseItems = new List<PurchaseItem>();
PurchaseItems.Add(new PurchaseItem(1, Purchases[0], Items[0]));
PurchaseItems.Add(new PurchaseItem(2, Purchases[0], Items[1]));
PurchaseItems.Add(new PurchaseItem(3, Purchases[0], Items[2]));
PurchaseItems.Add(new PurchaseItem(4, Purchases[0], Items[3]));
PurchaseItems.Add(new PurchaseItem(5, Purchases[0], Items[4]));
PurchaseItems.Add(new PurchaseItem(6, Purchases[0], Items[5]));
PurchaseItems.Add(new PurchaseItem(7, Purchases[1], Items[1]));
PurchaseItems.Add(new PurchaseItem(8, Purchases[2], Items[1]));
PurchaseItems.Add(new PurchaseItem(9, Purchases[2], Items[0]));
PurchaseItems.Add(new PurchaseItem(10, Purchases[2], Items[4]));
}
public void Dispose()
{
//Do nothing
}
}
public class Item
{
public int ID { get; set; }
public string Name { get; set; }
public IList<PurchaseItem> PurchaseItems { get; set; }
public Item()
{
PurchaseItems = new List<PurchaseItem>();
}
}
public class Purchase
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime? ConfirmedDate { get; set; }
public bool IsValid { get; set; }
public IList<PurchaseItem> PurchaseItems { get; set; }
public Purchase()
{
PurchaseItems = new List<PurchaseItem>();
}
}
public class PurchaseItem
{
public int ID { get; set; }
public int PurchaseId { get; set; }
public Purchase Purchase { get; set; }
public int ItemId { get; set; }
public Item Item { get; set; }
public PurchaseItem(int id, Purchase purchase, Item item)
{
ID = id;
PurchaseId = purchase.ID;
Purchase = purchase;
purchase.PurchaseItems.Add(this);
ItemId = item.ID;
Item = item;
item.PurchaseItems.Add(this);
}
}https://stackoverflow.com/questions/13463601
复制相似问题