2010-09-16 108 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;