Как переписать SQL-запрос в LINQ to Entities? - PullRequest
1 голос
/ 19 марта 2012

Я пытаюсь переписать запрос SQL в LINQ to Entities.Я использую LINQPad с типизированным текстовым текстом из собственной сборки, чтобы проверить его.

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 I 'Мы дошли до сих пор (что не работает из-за ошибки тайм-аута):

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 ]

1 голос
/ 19 марта 2012

Попробуйте это:

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
    };
0 голосов
/ 19 марта 2012

Я бы попробовал использовать 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();

Или вы можете попробовать joins с into и с anyтак что

 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
         };
0 голосов
/ 19 марта 2012

Я бы порекомендовал делать объединения, а не подбирать, как они есть. Подвыборы не очень эффективны, когда вы смотрите на производительность, это как циклы внутри циклов, когда вы кодируете, не очень хорошая идея. Это может привести к тому, что вы получите тайм-аут, если ваша база данных работает медленно, даже если это выглядит как простой запрос.

...