复杂的SQL子查询到LINQ

时间:2010-09-16 19:46:28

标签: c# sql database linq

我有这个SQL查询,这在LINQ中是不可能的。

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 个答案:

答案 0 :(得分:4)

尝试使用Linqer。我记得用它写了一些非常复杂的东西。

另外,您的查询并不是那么复杂,您只是从产品到其属性值。只需在键上做很多连接就可以了。

答案 1 :(得分:4)

我喜欢通过将查询的离散组件编写为单独的语句来编写Linq查询。因为每个语句都是查询而不是结果,所以Linq会在运行时将这些全部组合成一个SQL查询。

以这种方式编写查询对我来说非常容易阅读,而不会牺牲运行时数据库的性能,因为Linq无论如何都会在运行时将它变成一个大的查询。它会将以下查询中的包含转换为子选择。

使用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;

答案 2 :(得分:1)

我已经使用Contains()方法成功实现了'in'查询。例如:

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

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

以上内容将返回SomeTable的所有记录,其中id为1或4。

我相信你可以将Contains()方法链接在一起。我知道这似乎是倒退,但从最里面的子选择开始,然后从那里开始。

答案 3 :(得分: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;