Как ограничить LINQ, оставленный внешнее объединение одной строке

В последнее время вы можете использовать функцию intern, чтобы убедиться, что вы получаете ссылку на одну и ту же строку:

>>> a = intern('a')
>>> a2 = intern('a')
>>> a is a2
True

Как указано выше, вы, вероятно, не должны делать является определение равенства по строкам. Но это может быть полезно узнать, есть ли у вас какое-то странное требование использовать is.

Обратите внимание, что функция-интернатура перешла из встроенной функции в модуль sys для Python 3.

34
задан ahmed 29 January 2009 в 17:53
поделиться

3 ответа

Это сделает задание для Вас.

from i in db.items
let p = db.photos.Where(p2 => i.id == p2.item_id).FirstOrDefault()
orderby i.date descending
select new
{
  itemName = i.name,
  itemID = i.id,
  id = i.id,
  photoID = p == null ? null : p.PhotoID.ToString();
}

я получил этот sql, когда я генерировал его против своей собственной модели (и без имени и вторых идентификационных столбцов в проекции).

SELECT [t0].[Id] AS [Id], CONVERT(NVarChar,(
    SELECT [t2].[PhotoId]
    FROM (
        SELECT TOP (1) [t1].[PhotoId]
        FROM [dbo].[Photos] AS [t1]
        WHERE [t1].[Item_Id] = ([t0].[Id])
        ) AS [t2]
    )) AS [PhotoId]
FROM [dbo].[Items] AS [t0]
ORDER BY [t0].[Id] DESC

, Когда я попросил план, он показал, что подзапрос реализован этим соединением:

<RelOp LogicalOp="Left Outer Join" PhysicalOp="Nested Loops">
64
ответ дан 27 November 2019 в 06:55
поделиться

То, что Вы хотите сделать, является группой таблица. Лучший способ сделать это:

    var query = from i in db.items
                join p in (from p in db.photos
                           group p by p.item_id into gp
                           where gp.Count() > 0
                           select new { item_id = g.Key, Photo = g.First() })
            on i.id equals p.item_id into tempPhoto
            from tp in tempPhoto.DefaultIfEmpty()
            orderby i.date descending 
            select new
            {
                itemName = i.name,
                itemID = i.id,
                id = i.id,
                photoID = tp.Photo.PhotoID.ToString()
            };
<час>

Редактирование: Это - Amy B разговор. Я только делаю это, потому что Nick спросил меня к. Nick, измените или удалите этот раздел, как Вы себя чувствуете, является соответствующим.

сгенерированный SQL является довольно большим. Интервал 0 (чтобы быть по сравнению с количеством) передается на пути параметр.

SELECT [t0].X AS [id], CONVERT(NVarChar(MAX),(
    SELECT [t6].Y
    FROM (
        SELECT TOP (1) [t5].Y
        FROM [dbo].[Photos] AS [t5]
        WHERE (([t4].Y IS NULL) AND ([t5].Y IS NULL)) OR (([t4].Y IS NOT NULL) AND ([t5].Y IS NOT NULL) AND ([t4].Y = [t5].Y))
        ) AS [t6]
    )) AS [PhotoId]
FROM [dbo].[Items] AS [t0]
CROSS APPLY ((
        SELECT NULL AS [EMPTY]
        ) AS [t1]
    OUTER APPLY (
        SELECT [t3].Y
        FROM (
            SELECT COUNT(*) AS [value], [t2].Y
            FROM [dbo].[Photos] AS [t2]
            GROUP BY [t2].Y
            ) AS [t3]
        WHERE (([t0].X) = [t3].Y) AND ([t3].[value] > @p0)
        ) AS [t4])
ORDER BY [t0].Z DESC

план выполнения показывает три левых соединения. По крайней мере один тривиален и не должен считаться (это вводит нуль). Существует достаточно сложности здесь, что я не могу ясно указать ни на какую проблему для эффективности. Это могло бы работать большой.

5
ответ дан 27 November 2019 в 06:55
поделиться

Вы могли сделать что-то как:

var q = from c in
          (from s in args
           select s).First()
        select c;

Вокруг последней части запроса. Не уверенный, если это будет работать или какого ненормального SQL это произведет :)

4
ответ дан 27 November 2019 в 06:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: