【问题标题】:The LINQ expression 'OUTER APPLY Projection Mapping in EF .NET Core 5 ExceptionEF .NET Core 5 异常中的 LINQ 表达式“OUTER APPLY 投影映射”
【发布时间】:2021-01-09 17:40:57
【问题描述】:

从 .NET Core 2.x 迁移到 .NET Core 5.0 后,我们面临这个问题。

错误:(添加为代码以提高可读性)

 The LINQ expression 'OUTER APPLY Projection Mapping:
(
    SELECT e0.Id, e0.FirstName, e0.MiddleName, e0.LastName
    FROM Employees AS e0
    WHERE (((e0.Status != 4) && EXISTS (
        Projection Mapping:
        SELECT 1
        FROM FunctionRoles AS f0
        WHERE t.Id == f0.SchoolId)) && (e0.FunctionRoleId == (Projection Mapping:
            EmptyProjectionMember -> 0
        SELECT TOP(1) f1.Id
        FROM FunctionRoles AS f1
        WHERE (t.Id == f1.SchoolId) && (f1.Name == 'Manager')))) && (t.Id == e0.SchoolId)
) AS t0' could not be translated. Either rewrite the query in a form that can be translated, 
or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. 
See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

代码部分:

using (var dbContext = _contextProvider.CreateContext())
        {
            var school = dbContext.Set<Domain.Model.School>()
                .Where(s => s.Id == schoolId)
                .Select(s => new SchoolSummaryDto
                {
                    

                    //... Some other properties

                    DocumentTemplates = s.DocumentTemplates != null ? s.DocumentTemplates.Select(a => new DocumentTemplateDto
                    { Id = a.Id, Description = a.Description, SchoolId = a.SchoolId, FileName = a.FileName, DocumentTemplateTypeId = a.DocumentTemplateTypeId }).ToList() : new List<DocumentTemplateDto>(),

                    // This below chunk is causing problem.
                    Signers = s.Employees != null ? s.Employees.AsEnumerable().Where(
                        e => e.Status != PersistentStatusEnum.Removed &&
                        e.FunctionRoleId == s.FunctionRoles.AsEnumerable().Single(
                        b => b.Name == FunctionRolesEnum.Manager.ToString()).Id).AsEnumerable().Select(
                        a => new NameValueType { Id = a.Id, Name = string.Format("{0} {1} {2}", a.FirstName, a.MiddleName, a.LastName) }).ToList() : new List<NameValueType>(),
                    // .. Error chunk ends here

                    ContactPerson = s.ContactPerson,
                    Email = s.Email,
                    PhoneNumber = s.PhoneNumber,
                    SchoolId = s.Id,
                    SchoolName = s.Name,
                    Website = s.Website,
                    IsEnabled = s.IsEnabled,
                    IsRegistered = s.IsRegistered
                }).FirstOrDefault();

        }

我尝试了什么: 根据这些 Microsoft 链接 Breaking ChangesQueryable projection not supported,我尝试并相应地应用了更改 AsEnumerable(),如您在上面看到的。

现在需要进行哪些更改?

图书馆和环境:

  1. 数据库 => MySql
  2. 库 => Pomelo.EntityFrameworkCore.MySql (5.0.0-alpha.2) Nuget Link

我感觉这个 MySql 库导致问题或 EF Core 5 重大更改

编辑 1:

public class FunctionRole:AuditableEntity
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Guid SchoolId { get; set; }
    public virtual School School { get; set; }
}

public class School:AuditableEntity
{
    public bool IsRegistered { get; set; }
    public bool IsEnabled { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Website { get; set; }
    public string PhoneNumber { get; set; }
    public string ContactPerson { get; set; }
    public string ActivationCode { get; set; }

    public virtual ICollection<FunctionRole> FunctionRoles { get; set; }

    public virtual ICollection<DocumentTemplate> DocumentTemplates { get; set; }
    

}

【问题讨论】:

    标签: mysql entity-framework-core pomelo-entityframeworkcore-mysql ef-core-5.0


    【解决方案1】:

    我认为它适用于 EF 2.x,因为它会在客户端静默评估此查询。

    考虑重写查询:

     var query = 
       from s in dbContext.Set<Domain.Model.School>()
       where s.Id == schoolId
       from r in s.FunctionRoles
          .Where(b => b.Name == FunctionRolesEnum.Manager.ToString())
          .Take(1).DefaultIfEmpty()
       select new SchoolSummaryDto
       {
                        
          //... Some other properties
    
          DocumentTemplates = s.DocumentTemplates
             .Select(a => new DocumentTemplateDto
             { 
                Id = a.Id, 
                Description = a.Description, 
                SchoolId = a.SchoolId, 
                FileName = a.FileName, 
                DocumentTemplateTypeId = a.DocumentTemplateTypeId 
             })
             .ToList(),
    
           Signers = s.Employees
              .Where(e => e.Status != PersistentStatusEnum.Removed 
                          && e.FunctionRoleId == r.Id)
              .Select(a => new NameValueType 
              { 
                  Id = a.Id, 
                  Name = a.FirstName + " " + a.MiddleName + " " + a.LastName 
              })
              .ToList(),
    
           ContactPerson = s.ContactPerson,
           Email = s.Email,
           PhoneNumber = s.PhoneNumber,
           SchoolId = s.Id,
           SchoolName = s.Name,
           Website = s.Website,
           IsEnabled = s.IsEnabled,
           IsRegistered = s.IsRegistered
        };
    
    var school = query.FirstOrDefault();
    

    你不必检查空值,AsEnumerable 不需要,string.Format 不能翻译成 SQL。

    【讨论】:

    • 面临这个错误:System.InvalidOperationException: 'The LINQ expression 'ROW_NUMBER() OVER(PARTITION BY f.SchoolId ORDER BY f.Id ASC)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync
    • 用这三个实体发布你的模型。 EFC 疯了,翻译成 SQL 并抛出它不可翻译。此异常与s.FunctionRoles 翻译有关。
    • 请参阅编辑 1 部分。
    • 哦,看到了。看起来 Pomelo 提供者还没有将 ROW_NUMBER 窗口函数转换为 SQl。应该是一小时修复。
    • 嗯!让我们等待它发生。现在有什么快速解决办法吗?
    猜你喜欢
    • 2021-06-04
    • 2013-08-03
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2021-03-31
    • 1970-01-01
    相关资源
    最近更新 更多