Entity Framework中Lambda表达式的空值处理问题
解决Lambda表达式中Organization为空导致的查询报错问题
问题分析
原代码中,当c.Organization为空时,_db.Organizace.FirstOrDefault(a => a.Id == c.Organization)会返回null,后续调用.OrgName.ToString()会触发NullReferenceException。同时OrgName本身允许为空,无需强制调用ToString()。
解决方案
1. 空值判断+空条件运算符
直接通过HasValue判断c.Organization是否有值,再用?.空条件运算符避免组织对象为空时的报错:
var users = _userManager.Users.Select(c => new UsersViewModel() { Id = c.Id, Username = c.UserName, Email = c.Email, Role = string.Join(",", _userManager.GetRolesAsync(c).Result.ToArray()), OrgName = c.Organization.HasValue ? _db.Organizace.FirstOrDefault(a => a.Id == c.Organization)?.OrgName : null }).ToList();
2. 空合并运算符设置默认值
如果希望OrgName为空时显示空字符串而非null,可以结合??空合并运算符:
var users = _userManager.Users.Select(c => new UsersViewModel() { Id = c.Id, Username = c.UserName, Email = c.Email, Role = string.Join(",", _userManager.GetRolesAsync(c).Result.ToArray()), OrgName = c.Organization.HasValue ? _db.Organizace.FirstOrDefault(a => a.Id == c.Organization)?.OrgName ?? "" : "" }).ToList();
3. 优化查询性能(避免N+1问题)
原代码在Select中循环调用FirstOrDefault会产生N+1查询,建议用左外连接一次性关联查询:
var users = _userManager.Users .Join(_db.Organizace.DefaultIfEmpty(), user => user.Organization, org => org.Id, (user, org) => new UsersViewModel() { Id = user.Id, Username = user.UserName, Email = user.Email, Role = string.Join(",", _userManager.GetRolesAsync(user).Result.ToArray()), OrgName = org?.OrgName }) .ToList();
额外优化:避免同步调用异步方法死锁
原代码中_userManager.GetRolesAsync(c).Result可能导致死锁,建议改为异步处理:
// 将方法标记为async public async Task<List<UsersViewModel>> GetUsersAsync() { var users = await _userManager.Users .SelectAsync(async c => new UsersViewModel() { Id = c.Id, Username = c.UserName, Email = c.Email, Role = string.Join(",", await _userManager.GetRolesAsync(c)), OrgName = c.Organization.HasValue ? _db.Organizace.FirstOrDefault(a => a.Id == c.Organization)?.OrgName : null }); return users.ToList(); }
内容的提问来源于stack exchange,提问作者Jan Šalomoun
相关产品推荐
相关产品推荐

