简体   繁体   English

Linq 加入第二张表的记录

[英]Linq join with record of second table

I have looked at many similar question on SO but seems its not that straight forward.我已经看过很多关于 SO 的类似问题,但似乎并不那么简单。 The problem is, most of them are dealing with IEnumerable where in my case I have two IQueryable dbset s.问题是,他们中的大多数都在处理IEnumerable ,在我的情况下,我有两个IQueryable dbset

The situation is somewhat similar to the question here .情况与这里的问题有些相似。

Student
id     Name 
1      a1
2      b1
3      c1

Images
id   Image         StudentId      Status      ModifiedOn
1    1.jpg            1           Active      2021-03-12 02:02:32.580
2    2.jpg            1           Deleted     2021-03-12 02:01:32.580
3    3.jpg            2           Deleted     2021-03-12 02:02:32.580
4    4.jpg            2           Deleted     2021-03-12 02:01:32.580

Result should be Result应该是

id  Name Image
1   a1   1.jpg
2   b1   3.jpg
3   c1   NULL 

I can do this with TSQL and nested WITH qqueries, where one selects Status = Active, and the other selects Status,= Active.我可以使用 TSQL 和嵌套的 WITH qqueries 执行此操作,其中一个选择 Status = Active,另一个选择 Status,= Active。 then merge these two and select the TOP 1.然后合并这两个和 select TOP 1。

But since the requirement is to write the equivalent LINQ, I started with the below query, since I don't know a good way to do a merge of CASE WHEN on Status = Active.但由于要求是编写等效的 LINQ,因此我从以下查询开始,因为我不知道在 Status = Active 上合并 CASE WHEN 的好方法。

        var aquery = context.Images;
        var lquery = context.Students;
        var result = from l in lquery
                     join a in aquery on l.Id equals a.StudentId into aGroup
                     from a in aGroup.OrderByDescending(m => m.ModifiedOn).Take(1)
                     select new {
                         l.id,
                         a.StudentId,
                         a.Status
                     };

This failed the dbset s are not IEnumerable.这失败了dbset不是 IEnumerable。 Any idea how to get the correct result?知道如何获得正确的结果吗?

This query should work:此查询应该有效:

var query =
    from s in context.Students
    from i in context.Images
        .Where(i => i.StudentId = s.Id)
        .OrderBy(i => i.Status == "Active" ? 0 : 1)
        .ThenByDescending(i => i.ModifiedOn)
        .Take(1)
        .DefaultIfEmpty()
    select new 
    {
        s.Id,
        s.Name,
        i.Image
    };
 IQueryable<Image> images = context.Images.AsQueryable();
 IQueryable<Student> students = context.Students;

              
 var result =  (from st in students
                 select new
                    {
                        Id = st.Id,
                        Name = st.Name,
                        ImageName = images
                            .OrderBy(x => x.ModifiedAt)
                            .Where(x => x.Status)
                            .Where(i=> i.StudentId == st.Id)
                            .Select(x=> x.ImageName)
                            .FirstOrDefault()
                    })
                    .ToList();

But the easiest option is to define navigation field for images inside Student class:但最简单的选择是为 Student class 中的图像定义导航字段:

public class Student{

   List<Image> Images {get; private set;}
}

and then:接着:

 context.Students
         .Select(st=> new
                {
                  Id = st.Id,
                  Name = st.Name,
                  ImageName = st.Images
                                .OrderBy(x => x.ModifiedAt)
                                .Where(x => x.Status)
                                .Where(i=> i.StudentId == st.Id)
                                .Select(x=> x.ImageName)
                                .FirstOrDefault()
                 })
                 .ToList();

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

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