如何用LINQ实现两表左连接,无关联子表数据仍返回结果
问题分析
原查询的核心问题是左连接后的where条件错误过滤了无投票记录的Poll:当ff为null(对应Poll无任何投票或指定用户无投票)时,ff.PollGuid == guid的判断会返回false,导致这条Poll数据被排除,最终返回空数组。
正确LINQ写法
写法一:分组左连接(适配多关联场景)
var poll = ( from poll in ctx.TblPolls // 先筛选目标Poll where poll.Guid == guid // 左连接当前用户的投票记录 join userVote in ctx.TblVotes on new { PollGuid = poll.Guid, UserId = userId } equals new { userVote.PollGuid, userVote.UserId } into userVoteGroup from userVote in userVoteGroup.DefaultIfEmpty() // 左连接该Poll的所有投票记录用于统计总数 join allVote in ctx.TblVotes on poll.Guid equals allVote.PollGuid into allVotesGroup select new { poll.UserId, poll.Id, poll.Guid, poll.Question, poll.Description, poll.Date, poll.VideoId, // 用户无投票时返回null value = userVote?.Value, // 统计该Poll的总投票数 VoteCount = allVotesGroup.Count() } ).FirstOrDefault();
写法二:子查询(更简洁的单Poll查询)
var poll = ( from poll in ctx.TblPolls where poll.Guid == guid select new { poll.UserId, poll.Id, poll.Guid, poll.Question, poll.Description, poll.Date, poll.VideoId, // 子查询获取当前用户的投票值,无则返回null value = ctx.TblVotes.FirstOrDefault(v => v.PollGuid == poll.Guid && v.UserId == userId)?.Value, // 子查询统计该Poll的总投票数 VoteCount = ctx.TblVotes.Count(v => v.PollGuid == poll.Guid) } ).FirstOrDefault();
关键说明
- 两种写法都能确保:即使目标Poll无任何投票、或指定用户未给该Poll投票,依然返回Poll的完整数据,对应的
value字段为null。 - 写法二的子查询方式更简洁,EF Core会自动优化为对应的SQL语句,性能与分组连接相当。
内容的提问来源于stack exchange,提问作者redoc01
相关产品推荐
相关产品推荐

