2010-09-16 208 views
2

我有這個SQL查詢,這在LINQ中是不可能的。LINQ的複雜SQL子查詢

select * from attribute_value t0 
where t0.attribute_value_id in 
(
    select t1.attribute_value_id from product_attribute_value t1 
    where t1.product_attribute_id in 
    (
     select t2.product_attribute_id from product_attribute t2 
     where t2.product_id in 
     (
      select product_id from product p, manufacturer m 
      where p.manufacturer_id = m.manufacturer_id 
      and m.name = 'manufacturer name' 
     ) 
     and pa.attribute_id = 1207 
    ) 
) 

where子句也必須稍後在代碼中動態完成。

回答

4

嘗試使用Linqer。我記得用它寫了一些非常令人費解的事情。

在附註上,您的查詢並不是那麼複雜,您只是從產品到其屬性值。只需在鍵上進行大量連接即可完成。

+1

我不知道他是否爲他工作,但感謝分享,很酷的軟件! – 2010-09-16 19:52:10

+1

我很感興趣的是在該場景下看到該工具爲OP提供了什麼。 – eglasius 2010-09-17 00:18:58

1

我已經通過使用Contains()方法成功實現了'in'查詢。例如:

int[] ids = new int[] { 1, 4 }; 

databasecontext.SomeTable.Where(s => ids.Contains(s.id)); 

以上將返回從SomeTable所有記錄,其中ID爲1或4

我相信你可以鏈包含()方法一起使用。我知道它似乎倒退了,但從最內在的子選擇開始,並從那裏開始工作。

+0

查看Slaggg的回答以上 – Rohrbs 2010-09-16 21:47:25

4

我喜歡通過將查詢的離散組件寫爲單獨的語句來編寫Linq查詢。由於每條語句都是查詢而不是結果,因此Linq將在運行時將這些全部組合到一個SQL查詢中。

編寫查詢這樣一來,對我來說,使得它很容易閱讀,在不犧牲運行時數據庫的性能,因爲LINQ使成在運行時一個大的查詢反正。它會將以下查詢中的Contains轉換爲子選擇。

使用LinqPad查看生成的SQL - 查看SQL Linq創建的內容可能非常有趣。

注意結果本身就是一個查詢。要實現它,請執行result.ToList();

var productIds = from p in product 
       join m in manufacturer on p.manufacturer_id equals m.manufacturer_id 
       where m.name == 'manufacturer name' 
       select p.product_id; 

var productAttributeIds = from pa in product_attribute 
          where productIds.Contains(pa.product_id) 
          select pa.product_attribute_id; 

var attributeValueIds = from pav in product_attribute_value 
         where productAttributeIds.Contains(pav.product_attribute_id) 
         select pav.attribute_value_id; 

result = from av in attribute_value 
     where attributeValueIds.Contains(av.atttriute_value_id) 
     select av; 
+0

我不認爲這會按預期運行,至少不會在linq2sql的最後一個版本上運行,我試着做一個Contains over linq查詢。它不允許它,所以唯一的選擇就是執行productIds查詢並將這些ID發送到.Contains中。正因爲如此,你最終會得到幾分貝輪迴並接收/發送所有信息。 – eglasius 2010-09-17 00:18:20

+1

linq2sql會將該模式轉換爲select ... from ... where id in(select ...)。關鍵是不實現任何查詢(通過ToList()),但將它們留作查詢。然後Linq2Sql將它們全部合併爲一個大的Sql語句。 – Slaggg 2010-09-17 02:26:34

+0

@Slaggg你用過它嗎?我也希望它是這樣,但根據我的經驗,linq2sql不支持它,唯一的辦法是實現它/它具有我提到的問題。也許對它的支持被添加到.net 4,我還沒有嘗試過在這個版本中。 – eglasius 2010-09-17 17:25:23

1

取決於型號,但你應該能夠做到這一點類似於:

var attributes = 
    from t0 in db.AttributeValues 
    where t0.ProductAttributeValues.Any(t1=> 
     t1.ProductAttribute.AttributeId == 1207 && 
     t1.ProductAttribute.Product.Manufacturers 
      .Any(m=> m.name == "manufacturer name") 
    ) 
    select t0; 

一種替代,合理類似的查詢/只翻譯方法:

var attributes = 
    from t0 in db.AttributeValues 
    where db.Product_Attribute_Values.Any(t1 => 
     db.Product_Attributes.Any(t2 => 
      t2.product_attribute_id == t1.product_attribute_id && 
      db.Products.Any(p=> 
       p.product_id == t2.product_id && 
       db.Manufacturers.Any(m=> 
         m.manufacturer_id == p.manufacturer_id && 
         m.name == "manufacturer name" 
       ) 
      ) && 
      t2.attribute_id = 1207 
     ) && 
     t0.attribute_value_id == t1.attribute_value_id 
    ) 
    select t0;