Получить только одну (последнюю) запись в соединении один ко многим с linq-to-entity - PullRequest
5 голосов
/ 27 октября 2011

У меня есть следующее в linq-to-entity

clientprojects = (from p in this.SAPMappingEntities.SAP_Master_Projects 
join c in this.SAPMappingEntities.SAP_Master_ProjectPartners on c.project_no equals p.project_no
where c.partner_name.Contains(clientstring)
orderby p.start descending 
select new ClientProjects { client = c.partner_name, location = c.city +", "+c.region, project_no = c.project_no, start_dt = p.start, end_dt = p.finish }).Take(50).ToList();

Я бы хотел изменить этот запрос так, чтобы для каждого SAP_Master_Project получалась только запись SAP_Master_ProjectPartners, которая имеет самое последнее update_dt. Как я могу это сделать?

EDIT

Существует таблица проекта с номером проекта и деталями проекта, включая даты начала и окончания проекта. Есть таблица партнеров проекта с номером партнера проекта, именем, номером проекта, датой обновления и другими деталями.

SAP_MASTER_PROJECT

project_no

начать

отделка

SAP_MASTER_PROJECTPARTNERS

partner_no

project_no

PARTNER_NAME

город

регион

update_dt

Когда пользователь вводит «ABC» в текстовое поле, информация, которую я хочу вернуть, - это номер проекта, дата начала проекта, дата окончания проекта, а также имя партнера по проекту, город и штат из последней записи партнера по проекту для последние 50 проектов (на основе даты начала), в которых имя партнера по проекту содержит или похоже на «ABC».

Я уверен, что есть несколько способов сделать это, но его SQL дает мне результаты, которые мне нужны:

SELECT TOP 50 p.project_no, p.start, p.finish, c.partner_name, c.city, c.region
FROM 
(select pp.project_no, pp.partner_name, pp.city, pp.region
from SAP_Master_ProjectPartners pp
where pp.partner_name LIKE @clientstring AND pp.update_dt = (select max(pp1.update_dt)
                       from SAP_Master_ProjectPartners pp1
                       where pp1.project_no = pp.project_no)) c
join SAP_Master_Projects p
on (p.project_no = c.project_no)
ORDER BY p.start DESC

РЕДАКТИРОВАТЬ # 2 Этот sql на самом деле возвращает несколько элементов с одинаковым update_dt, поэтому я изменил sql ниже. Все еще пытается конвертировать в linq.

SELECT TOP 50 p.project_no, p.start, p.finish, c.partner_name, c.city, c.region, c.update_dt, c.row_id
FROM SAP_Master_Projects p
join
(select pp.project_no, pp.partner_name, pp.city, pp.region, pp.update_dt, pp.row_id
from SAP_Master_ProjectPartners pp
where pp.partner_name LIKE @clientstring AND pp.row_id = (select TOP 1 row_id
                       from SAP_Master_ProjectPartners pp1
                       where pp1.project_no = pp.project_no order by update_dt DESC)) c
on (p.project_no = c.project_no) where p.active_flag = 1
ORDER BY p.start DESC

Ответы [ 3 ]

8 голосов
/ 27 октября 2011

Этот запрос, вероятно, будет проще, если вы определите отношение сущностей между SAP_Master_Projects и SAP_Master_ProjectPartners, поэтому объединение может быть неявным, а не явным.

Редактировать Поскольку вы можете 'Для этого может сработать что-то подобное (использование let и логическое объединение в предложении where):

var clientProjects =
    (
        from p in entities.SAP_Master_Projects
        let c = entities.SAP_Master_ProjectPartners
            .Where(cl => cl.partner_name.Contains(clientstring)
                && cl.project_no == p.project_no
                )
            .OrderBy(cl => cl.update_dt) // Todo: Might need to be descending?
            .FirstOrDefault()
        where c != null
        orderby p.start descending
        select new ClientProjects
        {
            client = c.partner_name,
            location = c.city + ", " + c.region,
            project_no = c.project_no,
            start_dt = p.start,
            end_dt = p.finish
        }
        )
    .Take(50)
    .ToList()
    ;
1 голос
/ 27 октября 2011

Похоже, вы пытаетесь найти следующий запрос:

SELECT *
  FROM MasterProjects p
       INNER JOIN (SELECT project_no,
                          partner_name
                     FROM ProjectPartners o
                    WHERE o.update_dt = (SELECT MAX(update_dt)
                                           FROM ProjectPartners i
                                          WHERE i.project_no = o.project_no)) c
               ON p.project_no = c.project_no
              AND p.partner_name = c.partner_name

Я не совсем уверен, как перевести это в LINQ, но вот моя лучшая попытка:

var clientprojects =
    from p in MasterProjects
    join c in ProjectPartners on p.project_no == c.project_no
   where c.partner_name == (from o in ProjectPartners
                           where o.project_no == c.project_no
                             and o.update_dt == (from i in ProjectParters
                                                where o.project_no = i.project_no
                                               select i.update_dt).Max()
                          select o.partner_name).First();

Приведенный выше LINQ может даже не скомпилироваться, но, надеюсь, он отправит вас в правильном направлении.

0 голосов
/ 27 октября 2011

Я не говорю на вашем языке, извините.Но, например, в MySql вы можете добавить sort by update_dt DESC LIMIT 1 Вы можете сделать это или что-то подобное?

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