EF Core 7报错:LINQ表达式ProjectionBindingExpression无法转换问题求助
问题解决:EF Core 7 无法翻译 ProjectionBindingExpression 的 LINQ 查询
问题背景
从.NET 5迁移至.NET 7后,原有LINQ查询出现翻译失败错误:EF Core 7 - The LINQ expression 'ProjectionBindingExpression: 14' could not be translated,该查询在EF Core 5/6中可正常执行。
问题代码
var query = (from member in organization.Users let donor = member.Donor select new MembershipVM { UniqueIdentifier = member.UniqueIdentifier, Email = member.Email, LastDonation = (from donation in donor.Donations where donation.Fund.OrgId == organization.Id orderby donation.timeCreated descending select new MembershipVM.LastDonationVM { Amount = donation.Amount }).FirstOrDefault() })
修复方案
方案1:移除中间let绑定,直接使用导航属性
EF Core 7对let关键字的嵌套投影翻译存在bug,移除let donor = member.Donor,直接通过member.Donor.Donations访问关联数据,可规避翻译问题:
var query = from member in organization.Users select new MembershipVM { UniqueIdentifier = member.UniqueIdentifier, Email = member.Email, LastDonation = (from donation in member.Donor.Donations where donation.Fund.OrgId == organization.Id orderby donation.timeCreated descending select new MembershipVM.LastDonationVM { Amount = donation.Amount }).FirstOrDefault() };
方案2:改用方法链语法重构查询
方法链语法的结构更利于EF Core的翻译器解析,重构后的代码如下:
var query = organization.Users .Select(member => new MembershipVM { UniqueIdentifier = member.UniqueIdentifier, Email = member.Email, LastDonation = member.Donor.Donations .Where(donation => donation.Fund.OrgId == organization.Id) .OrderByDescending(donation => donation.timeCreated) .Select(donation => new MembershipVM.LastDonationVM { Amount = donation.Amount }) .FirstOrDefault() });
方案3:临时启用客户端评估(不推荐)
若上述方案无法生效,可临时允许客户端评估(注意:会导致部分查询逻辑在内存中执行,可能影响性能),在DbContext配置中添加:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseSqlServer("你的数据库连接字符串") .ConfigureWarnings(warnings => warnings.Ignore(CoreEventId.ClientEvaluationWarning)); }
说明
该问题是EF Core 7版本特有的查询翻译bug,后续官方更新可能修复此问题,优先推荐使用方案1或2调整查询结构来规避。
内容的提问来源于stack exchange,提问作者Isaac Ikusika
相关产品推荐
相关产品推荐

