如何在LINQ to Entities中重写SQL查询?

时间:2012-03-19 11:55:14

标签: c# sql linq linq-to-entities linqpad

我正在尝试在LINQ to Entities中重写SQL查询。我正在使用LINQPad和我自己的程序集中的类型化datacontext来测试。

我正在尝试重写的SQL查询:

SELECT DISTINCT variantID AS setID, option_value AS name, option_value_description AS description, sort_order as sortOrder
FROM all_products_option_names AS lst
WHERE lst.optionID=14 AND lst.productID IN (SELECT productID FROM all_products_option_names
                                            WHERE optionID=7 AND option_value IN (SELECT name FROM brands
                                                                                  WHERE brandID=1))
ORDER BY sortOrder;

到目前为止我提出的LINQ to Entities查询(由于超时错误而无效):

from a in all_products_option_names
where a.optionID == 14 && all_products_option_names.Any(x => x.productID == a.productID && x.optionID == 7 && brands.Any(y => y.name == x.option_value && y.brandID == 1))
select new
{
    id = a.variantID,
    name = a.option_value,
    description = a.option_value_description,
    sortOrder = a.sort_order,
}

这是我运行上述查询时遇到的错误:An error occurred while executing the command definition. See the inner exception for details.

内部例外是:Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

修改

我使用MySQL,这可能就是LINQPad没有向我展示生成的SQL的原因。

SQL版本没有超时。

编辑2:

我通过完全更改查询来解决问题,所以这个问题现在无关紧要了。

我认为史蒂文的反应是正确的,因为他最接近我想要实现的目标,他的反应给了我这个让我解决问题的想法。

3 个答案:

答案 0 :(得分:1)

试试这个:

var brandNames =
    from brand in db.Brands
    where brand.ID == 1
    select name;

var brandProductNames =
    from p in db.all_products_option_names
    where p.optionID == 7
    where brandNames.Contains(p.option_value)
    select p.productId;

var results =
    from p in db.all_products_option_names
    where p.optionID == 14
    where brandProductNames.Contains(p.productId)
    select new
    {
        setID = p.variantID, 
        name = p.option_value, 
        description = p.option_value_description, 
        sortOrder = p.sort_order
    };

答案 1 :(得分:0)

我建议你做加入而不是子选择。当您查看性能时,子选择效率不高,就像在编码时在循环内部循环,这不是一个好主意。如果您的数据库运行缓慢,这实际上可能导致您获得超时,即使您看起来像一个简单的查询。

答案 2 :(得分:0)

我最后会尝试使用joins distinct,如下所示:

var results =
    (from p in db.all_products_option_names
     join p2 in db.all_products_option_names on p.productId equals p2.productId
     join b in db.Brands on p2.option_value equals b.name
     where p.optionID == 14
     where p2.optionID == 7
     where b.BrandID == 1
     select new
     {
        setID = p.variantID, 
        name = p.option_value, 
        description = p.option_value_description, 
        sortOrder = p.sort_order
     }).Distinct();

或者您可以尝试将joinsintoany一样使用

 var results =
         from p in db.all_products_option_names
         join p2 in (from p3 in db.all_products_option_names.Where(x => x.optionId == 7) 
                     join b in db.Brands.Where(x => x.BrandID == 1) on p3.option_value equals b.name 
                     select p3) into pg
         where p.optionID == 14
         where pg.Any()
         select new
         {
            setID = p.variantID, 
            name = p.option_value, 
            description = p.option_value_description, 
            sortOrder = p.sort_order
         };