Linq-由于空值而无法加入表

时间:2018-07-21 19:53:49

标签: linq

我在连接多个表时遇到问题。 PatientID可以为null。每当PatientID为null时,它就无法加入,结果也不会添加到列表中。

关于我如何加入他们的任何建议?

        List<ViewActivityLogViewModel> q = new List<ViewActivityLogViewModel>();

        q = (from l in logs
                 join lc in logCategories on l.logCategoryID equals lc.logCategoryID
                 join p in patients on l.patientID equals p.patientID
                 join u in users on l.userIDInit equals u.userID
                 join ut in usertypes on u.userTypeID equals ut.userTypeID
                 join u2 in users on l.userIDApproved equals u2.userID
                 join ut2 in usertypes on u2.userTypeID equals ut2.userTypeID
                 select new ViewActivityLogViewModel
                 {
                    logID = l.logID,
                    logCategoryName =lc.logCategoryName,
                    firstName = p.firstName,
                    userIDInitfirstName = u.firstName,
                    userIDInituserTypeName = ut.userTypeName,
                    userIDApprovedfirstName = u2.firstName,
                    userIDApproveduserTypeName = ut2.userTypeName
                 }
                 ).OrderBy(x=>x.createDateTime).ToList();

这是我需要的答案。我用SQL编写的。

SELECT l.logID, lc.logCategoryName,p.firstName, p.lastName, u.firstName, ut.userTypeName,   u2.firstName,  ut2.userTypeName
FROM log AS l
LEFT JOIN patient AS p ON l.patientID = p.patientID
JOIN logCategory AS lc ON l.logCategoryID = lc.logCategoryID
JOIN user AS u ON l.userIDInit = u.userID
JOIN userType AS ut ON u.userTypeID = ut.userTypeID
JOIN user AS u2 ON l.userIDApproved = u2.userID
JOIN userType AS ut2 ON u2.userTypeID = ut2.userTypeID

3 个答案:

答案 0 :(得分:0)

您可以使用GroupJoin来加入patients表并获取数据。根据{{​​3}},GroupJoin中的Lambda支持LEFT JOIN中的SQL

  

GroupJoin保留外部元素的顺序,对于每个元素   外部元素,匹配元素从内部开始的顺序。

     

GroupJoin在   传统的关系数据库术语。但是,这种方法确实   实现内部联接和左外部联接的超集。两者的   这些操作可以按照分组连接的方式编写。

因此,您的查询可以写为

 var results = 
            logs.Join(logCategories, l => l.logCategoryID, lc => lc.logCategoryID, (l, lc) => new { l, lc })
            .Join(users, llc => new { userId = llc.l.userIDInit }, u1 => new { userId = u1.userID }, (llc, u1) => new { llc.l, llc.lc, u1 })
            .Join(userTypes, llcu1 => llcu1.u1.userTypeID, ut1 => ut1.userTypeID, (llcu1, ut1) => new { llcu1.l, llcu1.lc, llcu1.u1, ut1 })
            .Join(users, llcu2 => new { approvedId = llcu2.l.userIDApproved }, u2 => new { approvedId = u2.userID }, (llcu2, u2) => new { llcu2.l, llcu2.lc, llcu2.u1, llcu2.ut1, u2 })
            .Join(userTypes, llcu3 => llcu3.u2.userTypeID, ut2 => ut2.userTypeID, (llcu3, ut2) => new { llcu3.l, llcu3.lc, llcu3.u1, llcu3.u2, llcu3.ut1, ut2 })
            .GroupJoin(patients, llcu4 => llcu4.l.patientID, p => p.patientID, (llcu4, p) => new { llcu4.l, llcu4.lc, llcu4.u1, llcu4.u2, llcu4.ut1, llcu4.ut2, p })
            .SelectMany(x => x.p.DefaultIfEmpty(), (prj, y) => 
            {
                return new ViewActivityLogViewModel
                {
                    logID = prj.l.logID,
                    logCategoryName = prj.lc.logCategoryName,
                    firstName = y != null ? y.firstName : null,
                    userIDInitfirstName = prj.u1.firstName,
                    userIDInituserTypeName = prj.ut1.userTypeName,
                    userIDApprovedfirstName = prj.u2.firstName,
                    userIDApproveduserTypeName = prj.ut2.userTypeName
                };
            }).ToList();

MSDN和示例数据。

答案 1 :(得分:0)

我不确定你为什么 复制了只能在两个连接中实现的连接

JOIN user AS u ON l.userIDInit = u.userID
JOIN userType AS ut ON u.userTypeID = ut.userTypeID
JOIN user AS u2 ON l.userIDApproved = u2.userID
JOIN userType AS ut2 ON u2.userTypeID = ut2.userTypeID

JOIN user AS u ON l.userIDInit = u.userID and l.userIDApproved = u.userID
JOIN userType AS ut ON u.userTypeID = ut.userTypeID

以下查询将为您提供所需的结果

q = (from l in log
     join lc in logCategory
          on l.logCategoryID equals lc.logCategoryID
     join u in user 
          on new {a1=l.userIDInit,a2=l.userIDApproved} equals 
             new {a1=u.userID, a2=u.userID}
     join ut in userType
          on u.userTypeID equals ut.userTypeID
     join p in patient
          on l.patientID equals p.patientID
         into p11
     from p1 in p11.DefaultIfEmpty()
     select new {l,lc,u,ut,p1})
     .Select(x=>new ViewActivityLogViewModel
                {
                    logID = x.l.logID,
                    logCategoryName =x.lc.logCategoryName,
                    firstName = x.p1?.firstName,
                    userIDInitfirstName = x.u.firstName,
                    userIDInituserTypeName = x.ut.userTypeName,
                    userIDApprovedfirstName = x.u.firstName,
                    userIDApproveduserTypeName = x.ut.userTypeName
                 })
      .OrderBy(x=>x.createDateTime).ToList();

答案 2 :(得分:0)

您没有说哪个PatientId可以为null,所以为了安全起见,我假设两者都可以为null。

q = (from l in logs
     join lc in logCategories.Where(category => category.PatientId != null)
             on l.logCategoryID equals lc.logCategoryID

     join p in patients where(patient => patien.PatiendId != null)
             on l.patientID equals p.patientID

     join ...