繁体   English   中英

我如何在Linq(C#)中联接多个文件,其中联接之一是左联接

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

我的下面的Sql很好用,但是现在我想加入另一个具有公用密钥的文件。 我要加入的文件可能有一对多记录,任何建议

这是我的代码:

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

新的联接将是一对多的记录,其中CommunityPts中的键是Id,而我要联接的文件是带有外键CommnunityPtId的文件链接“ CommunityPtsDocs”的列表。 如何将其添加到上面的上述sql语句中?

进行以下修改将有助于完成任务,尽管我更喜欢Fluent语法,因为我认为在实现相同的目的时会更加干净,尽管我没有在Select语句中从CommunityPtsDocs中选择任何列

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

有时候,我觉得自己是一位导航属性的传播者(幸运的是,我并不是唯一的一个)。

您接受的答案可以,就可以了。 但是,使用任何ORM(例如Entity Framework或LINQ-to-SQL)时,应尽可能避免使用join语句。 这是冗长且容易出错的。 它会导致重复的代码,并且很容易错误地连接错误的属性。

您的CertPoint类可能具有0..1-n导航属性CommunityPts (列表),而CommunityPt可能具有1-n导航属性CommunityPtsDocs (也是列表)。 如果您使用的是LINQ-to-SQL,很可能它们已经存在,但是您不知道它们。 如果先使用Entity Framework代码,则应自己添加它们。

具有这些导航属性,您的代码将如下所示:

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

现在,ORM将使用正确的联接将其转换为SQL,并且您的代码看起来更加简洁(请注意,我也更喜欢有意义的范围变量名称)。

暂无
暂无

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

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