LINQ查询如何忽略无匹配行的关联表并返回其他表的有效数据
问题原因
你当前使用的是默认的**内连接(Inner Join)**关联VideoFiles和ImageFiles表,内连接的逻辑是仅当关联两侧的表都存在匹配行时,才会保留查询结果。只要这两张表中任意一张没有对应RoomId的匹配数据,整行符合条件的预约记录都会被过滤,所以会出现没有图片/视频时返回空结果的问题。
另外你原有查询里where d.IsActive == true || d.IsActive == false和where e.IsActive == true|| e.IsActive==false属于无效条件,布尔值只有这两种取值,完全可以省略。
修改方案
将VideoFiles和ImageFiles的关联改为**左外连接(Left Outer Join)**即可,LINQ中左外连接需要搭配into关键字和DefaultIfEmpty()方法实现,同时要注意关联对象为空时的空值判断,避免运行时抛出空引用异常。
修改后的代码如下:
from a in db.ApplySchedule join b in db.userdetails on a.UserID equals b.UserId join c in db.roomdetails on a.RoomID equals c.RoomId // 视频表改为左外连接 join d in db.VideoFiles on a.RoomID equals d.RoomId into videoGroup from d in videoGroup.DefaultIfEmpty() // 图片表改为左外连接 join e in db.ImageFiles on a.RoomID equals e.RoomId into imageGroup from e in imageGroup.DefaultIfEmpty() where EntityFunctions.TruncateTime(a.MDate) == EntityFunctions.TruncateTime(DateTime.Now) && a.RoomID == id && a.Status == true select new ShedulerViewModel { Id = a.BookingID, UserId = a.UserID, Uname = b.UserName, RoomId = a.RoomID, Rname = c.RoomName.ToUpper(), Organizer = a.SubjectDetail, Date = a.MDate, FromTime = a.start_date, ToTime = a.end_date, attend = a.Attend, // 空值判断,没有匹配的视频数据时赋值为null/默认值 VideoID = d != null ? d.RoomId : default(int?), VideoPath = d != null ? d.FilePath : null, videoIsActive = d != null ? d.IsActive : default(bool?), // 空值判断,没有匹配的图片数据时赋值为null/默认值 ImageId = e != null ? e.RoomId : default(int?), ImagePath = e != null ? e.FilePath : null, ImageIsActive = e != null ? e.IsActive : default(bool?) };
注意事项
如果你的ShedulerViewModel中VideoID、videoIsActive、ImageId、ImageIsActive这些字段是非可空的值类型,需要对应改为可空类型(比如int改成int?,bool改成bool?),否则没有匹配数据时赋值默认值可能会出现不符合预期的假值(比如bool默认是false,容易和实际的非激活状态混淆)。
内容的提问来源于stack exchange,提问作者Ashwin
相关产品推荐
相关产品推荐

