简体   繁体   中英

How do I join more than one files, in a Linq (C#) where one of the joins is a left join

My Sql below works great, but now I would like to join another file that has a common key. The file I would like to join has could have one to many records, any suggestions

here is my code:

 var regPoints = (from x in db.CertPoints
                                 join y in db.CommunityPts on x.PointId equals y.PointId into z
                                 from t in
                                     (from r in z
                                      where r.CommunityId == id select r).DefaultIfEmpty()
                                 where x.TypeId == 1 
                                 select new Points
                                 {
                                     pointId = x.PointId,
                                     pointsDescription = x.PointDescription,
                                     points = x.Points,
                                     dateApplied = t.DateApplied,
                                     pointsEarned = t.PointsEarned,
                                     pointsPending = t.Pending ? true : false,
                                     pointsApproved = t.Approved ? true : false,
                                     notes = t.Notes

                                 }).AsEnumerable();

the new join would be a one to many records, where the key in CommunityPts is Id, and the file I would like to join is a list of file links "CommunityPtsDocs" with a foreign key CommnunityPtId. How do i add it to the above sql statement above?

Following modification shall help in achieving the Task, though I prefer Fluent syntax, as that's much cleaner in my view to achieve the same, though I have not selected any column from CommunityPtsDocs in the Select statement

var regPoints = (from x in CertPoints
                 join y in CommunityPts on x.PointId equals y.PointId
                 join s in CommunityPtsDocs on y.Id equals s.CommnunityPtId into k
                 from t in (from r in k where r.CommunityId == id select r).DefaultIfEmpty()
                 where x.TypeId == 1 
                                 select new Points
                                 {
                                     pointId = x.PointId,
                                     pointsDescription = x.PointDescription,
                                     points = x.Points,
                                     dateApplied = t.DateApplied,
                                     pointsEarned = t.PointsEarned,
                                     pointsPending = t.Pending ? true : false,
                                     pointsApproved = t.Approved ? true : false,
                                     notes = t.Notes

                                 }).AsEnumerable();

Sometimes I feel I'm a navigation properties evangelist (fortunately, I'm not the only one).

The answer you accepted is OK, it does the job. But using any ORM like Entity Framework or LINQ-to-SQL you should avoid the join statement as much as possible. It's verbose and error-prone. It causes repetitive code and it's too easy to join the wrong properties erroneously.

You class CertPoint could have a 0..1-n navigation property CommunityPts (a list) and CommunityPt could have a 1-n navigation property CommunityPtsDocs (also a list). If you're using LINQ-to-SQL, chances are that they're already there but you're not aware of them. If you use Entity Framework code-first, you should add them yourself.

Having these navigation properties, your code is going to look like this:

from cert in CertPoints
from comm in cert.CommunityPts.DefaultIfEmpty()
from doc in comm.CommunityPtsDocs
where comm.CommunityId == id && cert.TypeId == 1 
select new Points
{
    pointId = cert.PointId,
    pointsDescription = cert.PointDescription,
    points = cert.Points,
    dateApplied = comm.DateApplied,
    pointsEarned = comm.PointsEarned,
    pointsPending = comm.Pending ? true : false,
    pointsApproved = comm.Approved ? true : false,
    notes = comm.Notes,
    something = doc.Something
})

Now the ORM will translate this into SQL with the correct joins and your code looks much cleaner (note that I also prefer more meaningful range variable names).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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