2012-02-27 12 views
0

まず第一に、私はLinqとLambda式の初心者だと認めなければならない。 私は(ラムダ式を使用して)のLINQステートメントに次のSQL文を取得しようとしている:同じテーブルを2回参照するには?

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) 

これは正常に動作しますが、明らかに不足している「とない存在...」の部分(最後の3行このポスティングの先頭にあるSQLコードを参照してください)。 私はLinqには "存在しません"がないことを知っていますが、これには "Any"メソッドを使用できます。

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

これは正常に動作してくれまだサプライヤーにリンクされていない任意の倉庫を与える: はここに私のコードでは、この他の場所での作業例です。 上記の例でわかるように、関連するテーブル「仕入先」を参照しているので、これは問題ありません。

しかし、私は今Linqに変換しようとしているSQLコードでは、 "存在しない"というのはリンクされたテーブルではなく、それ自体です。メインテーブルで2番目の参照を作成し、それを "..でない"という部分に使用する方法はありますか?多分何かのように:

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はStockTransferに第二のエイリアスになります)ST2を定義する方法がわかりません。 ご協力いただければ幸いです。

答えて

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

アリオン、あなたの答えに感謝します。私はそれを試していないが、私はそれが動作することがわかります。しかし、ああ、それは多くのコードです。だから私はラムダ式を使って動作させようとしたのです。数分前に投稿した回答を見てください。それは明らかに本当の答えではなく、私に正しい結果をもたらす回避策です。 – 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とラムダ式を使って解決策を考え出すことができれば嬉しいです。

関連する問題