首先,我必须承认我在Linq和Lambda表达式中非常新手。 我正在尝试将以下SQL语句转换为Linq语句(使用lamda表达式):
select *
from dbo.tblStockTransfers t1,
dbo.tblSuppliers t2
where t1.SupplierID = t2.SupplierID
and t2.WarehouseID in (1,2,3)
and t1.GoodsPickedUp = 1
and Not exists
(select 1 from dbo.tblStockTransfers t3
where t3.TransferOutID = t1.TransferID and t3.TransferConfirm = 1)
我的类StockTransfer是一个聚合根,拥有自己的存储库。 到目前为止,我得到了以下内容(变量allowedWarehouses包含仓库ID列表):
Return GetObjectSet().Where(Function(st) allowedWarehouses.Contains(st.Supplier.WarehouseID) And st.GoodsPickedUp = True)
这很好用,但显然缺少“而不存在...”部分(此帖子顶部的SQL代码的最后3行)。 我知道Linq没有“不存在”,但你可以使用“Any”方法。 以下是我的代码中其他地方的一个工作示例:
Return GetObjectSet().Where(Function(sw) sw.Active = True And Not sw.Suppliers.Any(Function(sp) sp.WarehouseID = sw.Id))
这很好,并且会给我任何与供应商无关的仓库。 正如您在上面的示例中所看到的,这很好,因为我指的是相关表“供应商”。
但是,在我现在尝试转换为Linq的SQL代码中,“not exists”不在链接表上,而是在其自身上。有没有办法在主表上创建第二个引用,并在“.. not..any”部分中使用它。也许是这样的:
Return GetObjectSet().Where(Function(st) allowedWarehouses.Contains(st.Supplier.WarehouseID) And st.GoodsPickedUp = True And Not st2.Any(st2.TransferOutID = st.TransferId and st2.TransferConfirm = true)
但我不知道如何定义st2(即在这种情况下st2将是StockTransfer的第二个别名)。 非常感谢任何帮助。
答案 0 :(得分:0)
我会这样做:
Dim lsWareHouseIds As New List(Of Integer)() From {1,2,3}
dim obj= ( _
From t1 in db.tblStockTransfers _
join t2 in db.tblSuppliers _
on t1.SupplierID equals company.SupplierID _
where lsWareHouseIds.Contains(t2.WarehouseID) _
andalso t1.GoodsPickedUp =1 _
andalso Not _
(
from t3 in db.tblStockTransfers _
where t3.TransferConfirm=1 _
select t3.TransferOutID _
).Contains(t1.TransferID) _
select t1 _
)
我确实看到你评论,你回答。你不能这样做:
GetObjectSet.Where(Function(st) _
allowedWarehouses.Contains(st.Supplier.WarehouseID) And st.GoodsPickedUp = True _
Andalso Not _
GetObjectSet.Where(Function(st) _
st.TransferConfirm = True).Any(Function(x) x.Id = st.TransferOutID)).ToList
答案 1 :(得分:0)
这不是问题的答案,但这是一个解决办法,它确实能让我得到我需要的结果:
Dim st1 As List(Of StockTransfer) = GetObjectSet.Where(Function(st) allowedWarehouses.Contains(st.Supplier.WarehouseID) And st.GoodsPickedUp = True).ToList
Dim st2 As List(Of StockTransfer) = GetObjectSet.Where(Function(st) st.TransferConfirm = True).ToList
For Each st As StockTransfer In st2
st1.RemoveAll(Function(x) x.Id = st.TransferOutID)
Next
Return st1
我显然是通过将查询拆分为两部分来作弊,其中每个部分最终都在列表中,然后我从列表1中删除我在列表2中获得的任何项目(删除通常为被“不存在”部分忽略了。
但是,如果有人能够使用Linq和lambda表达式提出一个有效的解决方案(我觉得这有点像作弊),我很乐意听到它。