LINQ to Entities报错:指定类型成员DateofLastQuote不支持,求解决
解决方案
问题根源
- LINQ to Entities不支持将**实体对象(如
Account)**作为GroupBy的分组键,也无法将实体对象的相等比较转换为SQL连接条件。 - 模型中的
AccountName、AccountOrgId是计算属性,EF无法将其转换为SQL语句,在IQueryable查询阶段会报错。 - 直接使用
DateTime字段分组时,若包含时间部分可能导致分组逻辑不符合预期,且EF对部分DateTime操作的支持有限。
修改步骤
1. 重构GroupBy逻辑,使用字段而非实体对象分组
将GroupBy的键替换为Account的主键及所需字段,同时截断DateOfLastQuote的时间部分以保证分组逻辑准确:
// 分组并连接查询 revenueQuery = revenueQuery .GroupBy(r => new { AccountId = r.Account.Id, AccountName = r.Account.Name, AccountOrgId = r.Account.OrganizationId, r.AccountManager, r.AccountExecutive, r.WholesaleRegionalSalesExecutive, r.PartnerName, r.PartnerOrgId, DateOfLastQuote = DbFunctions.TruncateTime(r.DateOfLastQuote) })
2. 修改Join条件,使用主键字段连接
将Join的关联条件从实体对象改为Account.Id主键,确保EF能生成正确的SQL连接语句:
.Join(quoteQuery, r => r.Key.AccountId, // 用分组键中的AccountId作为关联条件 q => q.Account.Id, // 用quoteQuery中Account的Id作为关联条件 (r, q) => new RevenueByAccount { // 显式赋值所有字段,避免依赖计算属性 AccountName = r.Key.AccountName, AccountOrgId = r.Key.AccountOrgId, AccountManager = r.Key.AccountManager, AccountExecutive = r.Key.AccountExecutive, WholesaleRegionalSalesExecutive = r.Key.WholesaleRegionalSalesExecutive, PartnerName = r.Key.PartnerName, PartnerOrgId = r.Key.PartnerOrgId, DateOfLastQuote = DbFunctions.TruncateTime(q.Created) // 若必须保留Account实体,可在此处构造:Account = new Account { Id = r.Key.AccountId, Name = r.Key.AccountName, OrganizationId = r.Key.AccountOrgId } })
3. 调整模型计算属性(可选)
如果不需要保留Account实体属性,可以移除模型中的Account字段,直接保留AccountName和AccountOrgId的普通属性,避免计算属性带来的EF查询问题:
public class RevenueByAccount { // 移除Account实体属性 // public Account Account { get; set; } public decimal Amount { get; set; } [Display(Name = "Account")] public string AccountName { get; set; } // 改为普通属性 [Display(Name = "Org ID")] public string AccountOrgId { get; set; } // 改为普通属性 // 其余属性保持不变... }
4. 调整排序字段
排序时使用实体中存在的普通属性,而非计算属性或实体对象:
revenueQuery = revenueGrid.Sorter.Sort(revenueQuery, fieldHelper.GetName(f => f.AccountName));
完整修改后的代码片段
// 获取收入查询 var revenueQuery = invoiceAllocationRepository.GetRevenuesByPartner(revenueGrid.StartDate, revenueGrid.EndDate, accountFilterId: revenueGrid.AccountFilter.Id, reviewedOnly: _context.AccountType == AccountType.System ? false : true); // 分组并连接查询 revenueQuery = revenueQuery .GroupBy(r => new { AccountId = r.Account.Id, AccountName = r.Account.Name, AccountOrgId = r.Account.OrganizationId, r.AccountManager, r.AccountExecutive, r.WholesaleRegionalSalesExecutive, r.PartnerName, r.PartnerOrgId, DateOfLastQuote = DbFunctions.TruncateTime(r.DateOfLastQuote) }) .Join(quoteQuery, r => r.Key.AccountId, q => q.Account.Id, (r, q) => new RevenueByAccount { AccountName = r.Key.AccountName, AccountOrgId = r.Key.AccountOrgId, AccountManager = r.Key.AccountManager, AccountExecutive = r.Key.AccountExecutive, WholesaleRegionalSalesExecutive = r.Key.WholesaleRegionalSalesExecutive, PartnerName = r.Key.PartnerName, PartnerOrgId = r.Key.PartnerOrgId, DateOfLastQuote = DbFunctions.TruncateTime(q.Created) }); revenueQuery = revenueGrid.Sorter.Sort(revenueQuery, fieldHelper.GetName(f => f.AccountName)); revenueGrid.Revenues = revenueGrid.Pager.Page(revenueQuery).ToList();
内容的提问来源于stack exchange,提问作者ray805
相关产品推荐
相关产品推荐

