2012-02-27 5 views
0

Прежде всего, я должен признать, что я очень новичок в выражениях 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 содержит список идентификаторов склада):

Return GetObjectSet().Where(Function(st) allowedWarehouses.Contains(st.Supplier.WarehouseID) And st.GoodsPickedUp = True) 

Это работает отлично, но, очевидно, отсутствует «и не существует ...» часть (последние 3 строк кода SQL в верхней части этой публикации). Я знаю, что Linq не имеет «не существует», но вы можете использовать для этого метод «Любой». Вот рабочий пример этого в другом месте в моем коде:

Return GetObjectSet().Where(Function(sw) sw.Active = True And Not sw.Suppliers.Any(Function(sp) sp.WarehouseID = sw.Id)) 

Это прекрасно работает, и даст мне какие-либо склады, которые не связаны с поставщиком еще. Как вы можете видеть в приведенном выше примере, это прекрасно, поскольку я имею в виду связанную таблицу «Поставщики».

Однако в коде SQL, который я сейчас пытаюсь преобразовать в Linq, «не существует» не находится в связанной таблице, а на самом деле. Есть ли способ создать вторую ссылку в главной таблице и использовать ее в разделе «.. 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

Я хотел бы сделать это что-то вроде этого:

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 
+0

Arion, спасибо за ваш ответ. Я не пробовал, но я вижу, что это сработает. Но, черт возьми, это много кода. Вот почему я попытался заставить его работать с использованием лямбда-выражений. Посмотрите на ответ, который я опубликовал несколько минут назад. это, очевидно, не настоящий ответ, а работа, которая дает мне правильный результат. – Peter

+0

Обновлен ответ – Arion

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 

Я очевидно, обманывая, разбивая запрос на 2 части, где каждая часть заканчивается в списке, а затем я удаляю из списка 1 все элементы, которые у меня есть в списке 2 (удаление тех, которые обычно игнорируются «не существует» " часть).

Тем не менее, я хотел бы услышать его, если кто-нибудь может придумать рабочее решение, используя выражения Linq и лямбда (так как это немного похоже на обман).