【问题标题】:LINQ Lambda - Join, DistinctLINQ Lambda - 加入,不同
【发布时间】:2014-12-01 01:06:11
【问题描述】:

我仍在学习开发 LINQ lambda 表达式。

我有一个父表 Requests 和一个子表 Sponsor,它们将有 0 或 1 行与请求相关联。我想显示用户可能在他/她之前的任何请求中定义的过去赞助商的列表。

第一个:我可以找到用户之前输入的所有请求(Request.UserId == 1111);

第二个:表是通过RequestId关联的(request.RequestId == Sponsor.RequestId);

3rd:我想限制基于不同的 Sponsor.Email 返回的行(根据不同的 Sponsor.Email 返回最大的 Sponsor.RequestId);

4th:我希望它们按使用的最新赞助商排序(按 Sponsor.RequestId 降序排序);

最后一个警告,如果 Sponsor.LastNm 不为空(以前的升级问题),我只想返回赞助商记录。

所以我很接近,但我不是基于相同的电子邮件过滤掉:

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

至少我需要返回 Request.DateRequested 和整个 Sponsor 行。

请求表(仅某些列)

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

赞助商表(仅限某些栏目)

RequestId   Email                LastNm
12          abc.xyz.com
34          abc@xyz.com          Doe
87          abc@xyz.com          Doe
99          def@xyz.com          Doe

所以我想返回以下行

Request.DateRequested   Sponsor
2013-11-15              99, def@xyz.com, Doe
2013-11-02              87, abc@xyz.com, DOe

【问题讨论】:

    标签: c# linq lambda


    【解决方案1】:

    我发现以查询语法样式编写 LINQ 查询更容易。它确实提高了我的可读性。

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

    坚持使用函数表示法,应该是:

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

    这会产生我认为您想要的结果。在两个单独的数组中使用数据的本地副本,并使用以下循环:

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

    我明白了:

    11/15/2013 12:00:00 AM  99      def@xyz.com     Doe
    11/2/2013 12:00:00 AM   87      abc@xyz.com     Doe
    

    此外,如果您的数据库中具有参照完整性并且正在使用 EntityFramework(或 OpenAccess),您可以将连接替换为两个 froms。

    from r in requests
    from s in r.sponsors
    

    【讨论】:

    • 根据您完成的函数符号和关于 RI 的最终评论,我重新编写了代码:var qry = db.requests .Where(req => req.UserID == 111 && req.Sponsor != null && req.Sponsor.Lastnm != null) .OrderByDescending(req => req.RequestID) .GroupBy(req => req.Sponsor.EMail) .Select(group => group.First());
    猜你喜欢
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多