Сложный SQL-подзапрос к LINQ - PullRequest
       2

Сложный SQL-подзапрос к LINQ

2 голосов
/ 16 сентября 2010

У меня есть 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 ]

4 голосов
/ 17 сентября 2010

Мне нравится составлять запросы 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;
4 голосов
/ 16 сентября 2010

Попробуйте использовать Linqer .Я помню, как писал несколько действительно запутанных вещей.

Кстати, ваш запрос не настолько сложен, вы просто переходите от продукта к его значениям атрибута.Просто сделайте много соединений на ключах, и все готово.

1 голос
/ 17 сентября 2010

Зависит от модели, но вы должны быть в состоянии сделать это так:

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;
1 голос
/ 17 сентября 2010

Я успешно реализовал запросы in, используя метод Contains (). Например:

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

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

Выше будут возвращены все записи из SomeTable, где id равен 1 или 4.

Полагаю, вы можете объединить методы Contains () вместе. Я знаю, что это кажется задом наперед, но начните с самого внутреннего подвыбора и продолжайте свой путь оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...