EF Core中EmptyProjectionMember错误排查:人员在馆统计查询问题
问题解决:EF Core查询Access数据库时出现"EmptyProjectionMember"错误
错误原因
这个错误是因为EF Core的Access数据库提供程序在处理GroupBy后直接调用OrderByDescending().FirstOrDefault()的查询逻辑时,无法正确转换为Access兼容的SQL语法,导致投影成员解析失败。
解决方案
方案1:改用子查询获取最后记录(推荐)
通过子查询先获取每个目标人员的最新访问时间,再关联原表筛选状态,这种写法更易被Access提供程序正确转换:
var latestAccessTimes = _context.AccessDatas .Where(a => a.AccessType == 2) .GroupBy(a => a.PersonId) .Select(g => new { PersonId = g.Key, LatestTime = g.Max(a => a.AccessTime) }); var totalInsideVisitors = await _context.AccessDatas .Join(latestAccessTimes, a => new { a.PersonId, a.AccessTime }, lat => new { lat.PersonId, lat.LatestTime }, (a, lat) => a) .Where(a => a.GC == 1) .CountAsync();
方案2:简化GroupBy逻辑
原查询中GroupBy包含AccessType是冗余的(已经通过Where限定了AccessType=2),简化后可能避免转换异常:
var totalInsideVisitors = await _context.AccessDatas .Where(a => a.AccessType == 2) .GroupBy(a => a.PersonId) .Select(g => g.OrderByDescending(a => a.AccessTime).FirstOrDefault()) .Where(a => a != null && a.GC == 1) .CountAsync();
方案3:内存中处理(小数据量场景)
如果数据量不大,可以先将符合条件的数据加载到内存再处理,绕过EF Core的SQL转换问题:
var totalInsideVisitors = (await _context.AccessDatas .Where(a => a.AccessType == 2) .ToListAsync()) .GroupBy(a => a.PersonId) .Select(g => g.OrderByDescending(a => a.AccessTime).FirstOrDefault()) .Count(a => a != null && a.GC == 1);
说明
优先使用方案1,因为它的SQL转换逻辑更通用,Access数据库对MAX()聚合和JOIN的支持更稳定,不会出现投影解析错误。
内容的提问来源于stack exchange,提问作者Gökhan YILDIZ
相关产品推荐
相关产品推荐

