简体   繁体   English

在linq-to-entities的一对多连接中只获得一条(最后一条)记录

[英]Get only one (last) record in one-to-many join with linq-to-entities

I have the following in linq-to-entities 我在linq-to-entities中有以下内容

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();

I would like change this query so that for each SAP_Master_Project only get the SAP_Master_ProjectPartners record which has the latest update_dt. 我想更改此查询,以便每个SAP_Master_Project只获取具有最新update_dt的SAP_Master_ProjectPartners记录。 How can I do this? 我怎样才能做到这一点?

EDIT 编辑

There's a project table with a project number and project details including project start and end dates. 有一个项目表,其中包含项目编号和项目详细信息,包括项目开始和结束日期。 There's a project partners table with the project partner number, name, project number, update date and other details. 有一个项目合作伙伴表,其中包含项目合作伙伴编号,名称,项目编号,更新日期和其他详细信息。

SAP_MASTER_PROJECT SAP_MASTER_PROJECT

project_no project_no

start 开始

finish

SAP_MASTER_PROJECTPARTNERS SAP_MASTER_PROJECTPARTNERS

partner_no partner_no

project_no project_no

partner_name PARTNER_NAME

city

region 区域

update_dt update_dt

When the user enters "ABC" into a text box, the info I want to return is the project number, project start date, project end date plus project partner name, city, and state from the last project partner record for the last 50 projects (based on start date) where the project partner name contains or is like "ABC". 当用户在文本框中输入“ABC”时,我要返回的信息是项目编号,项目开始日期,项目结束日期加上项目合作伙伴名称,城市和最近50个项目的最后一个项目合作伙伴记录的状态(基于开始日期)项目合作伙伴名称包含或类似“ABC”。

I'm sure there's more than one way to do this, but his SQL gives me the results that I need: 我确信有多种方法可以做到这一点,但他的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

EDIT #2 That sql actually returns a few items which have the same update_dt, so I modified the sql to below. 编辑#2 sql实际上返回了一些具有相同update_dt的项目,所以我将sql修改为如下。 Still struggling to convert to linq. 仍在努力转换为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

This query would probably be simpler if you defined an entity relationship between SAP_Master_Projects and SAP_Master_ProjectPartners so the join could be implicit instead of explicit. 如果您在SAP_Master_ProjectsSAP_Master_ProjectPartners之间定义了实体关系,则此查询可能会更简单,因此连接可以是隐式的而不是显式的。

Edit Since you can't do that, something like this might work (using let and doing a logical join within a where clause): 编辑因为你不能这样做,这样的事情可能会起作用(使用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()
    ;

It sounds like you're trying to come up with the following query: 听起来你正试图提出以下查询:

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

I'm not entirely sure how to translate this in to LINQ but here is my best attempt: 我不完全确定如何将其转换为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();

The above LINQ may not even compile, but hopefully it'll send you in the right direction. 上面的LINQ甚至可能都没有编译,但希望它会向你发送正确的方向。

I don't speak your language, sorry. 对不起,我不会说你的语言。 But, for instance, in MySql you might add sort by update_dt DESC LIMIT 1 can you do that or somethign similar? 但是,例如,在MySql中你可以sort by update_dt DESC LIMIT 1添加sort by update_dt DESC LIMIT 1你可以这样做或者某些类似吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM