[英]LINQ Lambda - Join, Distinct
I am still learning to develop LINQ lambda expressions. 我仍在学习开发LINQ lambda表达式。
I have a parent table Requests and a child table Sponsor that will have 0 or 1 row associated with a request. 我有一个父表“ Requests”和一个子表“ Sponsor”,它将有0或1行与一个请求相关联。 I would like to show a list of past sponsors that a user might have defined in any of his/her previous requests. 我想显示用户在以前的任何请求中可能已经定义的过去赞助者的列表。
1st: I can find all previous requests entered by a user (Request.UserId == 1111); 1st:我可以找到用户输入的所有先前请求(Request.UserId == 1111);
2nd: The tables are associated by RequestId (request.RequestId == Sponsor.RequestId); 第二:表格由RequestId关联(request.RequestId == Sponsor.RequestId);
3rd: I want to limit the rows returned based on distinct Sponsor.Email (return the max Sponsor.RequestId based on distinct Sponsor.Email); 第三:我想限制基于不同的Sponsor.Email返回的行(基于不同的Sponsor.Email返回最大Sponsor.RequestId);
4th: I want them ordered by the latest sponsor used (order by descending Sponsor.RequestId); 第四:我希望它们由使用的最新赞助商订购(按Sponsor.RequestId降序订购);
One last caveat, I only want to return sponsor records were the Sponsor.LastNm is not null (A previous upgrade issue). 最后一个警告,我只想返回赞助商记录的是Sponsor.LastNm不为null(先前的升级问题)。
So I am close, but I am not filtering out based on emails being the same: 所以我很接近,但是我并没有基于相同的电子邮件进行过滤:
db.Requests
.Where (req => req.UserID == 1111)
.Join(db.Sponsors,
req => req.RequestID,
spon => spon.RequestID,
(req, spon) => new { Requests = req, Sponsors = spon })
.Where(both => both.Sponsors.LastNm != null)
.OrderByDescending(both => both.Sponsors.RequestID);
At a minimum I need the Request.DateRequested and entire Sponsor row returned. 至少我需要Request.DateRequested并返回整个发起人行。
Request Table (only certain columns) 请求表(仅某些列)
RequestId UserId DateRequested
12 1111 2013-10-12
34 1111 2013-10-23
56 2222 2013-10-25
87 1111 2013-11-02
99 1111 2013-11-15
Sponsor Table (only certain columns) 赞助者表(仅某些列)
RequestId Email LastNm
12 abc.xyz.com
34 abc@xyz.com Doe
87 abc@xyz.com Doe
99 def@xyz.com Doe
So I would like to have the following rows returned 所以我想返回以下行
Request.DateRequested Sponsor
2013-11-15 99, def@xyz.com, Doe
2013-11-02 87, abc@xyz.com, DOe
I find it easier to write my LINQ queries in query syntax style. 我发现以查询语法样式编写LINQ查询更加容易。 It really does improve readability for me. 它确实为我提高了可读性。
var qry = from r in db.Requests
join s in db.Sponsors on r.RequestID equals s.RequestID
where r.UserID == 111 &&
s.LastNm != null
orderby s.RequestID descending
group new { Request = r, Sponsor = s } by s.EMail into g
select g.First();
Sticking with function notation, it would be: 坚持使用功能符号,它将是:
var qry = db.requests
.Where(req => req.UserID == 111)
.Join(db.sponsors,
req => req.RequestID,
spon => spon.RequestID,
(req, spon) => new { Requests = req, Sponsor = spon })
.Where(both => both.Sponsor.LastNm != null)
.OrderByDescending(both => both.Sponsor.RequestID)
.GroupBy(both => both.Sponsor.EMail)
.Select(group => group.First());
This produces the result I think you are going for. 这产生了我认为您想要的结果。 With a local replica of your data in two separate arrays,and using the following loop: 在两个单独的数组中使用数据的本地副本,并使用以下循环:
foreach (var rec in qry)
Console.WriteLine("{0}\t{1}\t{2}\t{3}", rec.Request.DateRequested, rec.Request.RequestID, rec.Sponsor.EMail, rec.Sponsor.LastNm);
I get: 我得到:
11/15/2013 12:00:00 AM 99 def@xyz.com Doe
11/2/2013 12:00:00 AM 87 abc@xyz.com Doe
Also, if you have referential integrity in your database and are using EntityFramework (or OpenAccess) you can replace the join with two froms. 另外,如果您的数据库具有参照完整性,并且正在使用EntityFramework(或OpenAccess),则可以用两个froms替换联接。
from r in requests
from s in r.sponsors
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.