【问题标题】:ASP.NET MVC Query with both CASE statement and SUM function带有 CASE 语句和 SUM 函数的 ASP.NET MVC 查询
【发布时间】:2021-12-17 05:05:57
【问题描述】:

我已经找到了一些解决这个问题的方法,但我不知道为什么它不起作用...... 我正在使用 ASP.NET MVC

我的数据库有 2 个表:HealthRegister & Member

每个 HealthRegister 有一个成员,每个成员有多个成员。

public class HealthRegistration
    {
        [Key]
        public int HealthRegistrationID { get; set; }
        [ForeignKey("Member")]
        public string MemberRegistrationNumber { get; set; }
        [Display(Name = "Data e hora do registro")]
        public DateTime RegisterDateTime { get; set; }
        [Display(Name = "Está de sentindo bem?")]
        public bool HowRUFeeling { get; set; }
        [Display(Name = "Falta de ar")]
        public bool FaltaDeAr { get; set; }
        [Display(Name = "Cansaço")]
        public bool Cansaco { get; set; }
        [Display(Name = "Febre")]
        public bool Febre { get; set; }
        [Display(Name = "Calafrios")]
        public bool Calafrios { get; set; }
        [Display(Name = "Tosse")]
        public bool Tosse { get; set; }
        [Display(Name = "Dor de garganta")]
        public bool DorDeGarganta { get; set; }
        [Display(Name = "Dor de cabeça")]
        public bool DorDeCabeca { get; set; }
        [Display(Name = "Dor no peito")]
        public bool DorNoPeito { get; set; }
        [Display(Name = "Perda de olfato")]
        public bool PerdaDeOlfato { get; set; }
        [Display(Name = "Perda de paladar")]
        public bool PerdaPaladar { get; set; }
        [Display(Name = "Diarreia")]
        public bool Diarreia { get; set; }
        [Display(Name = "Coriza")]
        public bool Coriza { get; set; }
        [Display(Name = "Espirros")]
        public bool Espirros { get; set; }
        public virtual Member Member { get; set; }
    }

public class Member
    {
        public enum Sectors
        {
            Administrador,
            Aluno,
            Professor,
            Funcionario            
        }

        [Key]
        [Display(Name = "Número de matrícula")]
        public string MemberRegistrationNumber { get; set; }
        [Display(Name = "Nome")]
        public string Name { get; set; }
        [Display(Name = "Setor")]
        public Sectors Sector { get; set; }
        [Display(Name = "Senha")]
        public string Password { get; set; }
        [Column(TypeName = "Date")]
        [Display(Name = "Data de nascimento")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
        [DataType(DataType.Date)]
        public DateTime BirthDate { get; set; }
        [Display(Name = "Cidade")]
        public string City { get; set; }
        [Display(Name = "Estado")]
        public string State { get; set; }
        [Display(Name = "Administrador")]
        public bool Admin { get; set; }
        [Display(Name = "Registros de saúde")]
        public virtual ICollection<HealthRegistration> HealthRegistrations { get; set; }
    }

我想在 ASP.NET MVC 中进行以下 SQL 查询:

SELECT
    CONVERT(DATE, RegisterDateTime),
    SUM(CASE WHEN Sector = 0 THEN 1 ELSE 0 END),
    SUM(CASE WHEN Sector = 1 THEN 1 ELSE 0 END),
    SUM(CASE WHEN Sector = 2 THEN 1 ELSE 0 END),
    SUM(CASE WHEN Sector = 3 THEN 1 ELSE 0 END)
FROM
    [dbo].[HealthRegistration]
    INNER JOIN
    [dbo].[Member]
    ON [dbo].[Member].MemberRegistrationNumber = [dbo].[HealthRegistration].MemberRegistrationNumber
GROUP BY CONVERT(DATE, RegisterDateTime);

我已尝试此解决方案,但出现错误消息:

var registerBySectorByDate = await _context.HealthRegistration
                .Include(m => m.Member)
                .Where(m => DateTime.Compare(m.RegisterDateTime, fromDate) >= 0 && DateTime.Compare(m.RegisterDateTime, toDate) <= 0)
                .GroupBy(m => m.RegisterDateTime.Date)
                .Select(m => new
                {
                    Key = m.Key,
                    x = m.Sum(n => n.Member.Sector == Member.Sectors.Administrador ? 1 : 0)
}).ToListAsync();

错误信息:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: The LINQ expression 'GroupByShaperExpression:
      KeySelector: CONVERT(date, h.RegisterDateTime),
      ElementSelector:EntityShaperExpression:
          EntityType: HealthRegistration
          ValueBufferExpression:
              ProjectionBindingExpression: EmptyProjectionMember
          IsNullable: False

          .Sum(n => (int)n.Member.Sector == 0 ? 1 : 0)' 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.
         at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
         at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
         at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
         at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression)
         at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
         at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
         at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitNew(NewExpression newExpression)
         at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
         at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
         at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
         at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
         at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
         at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
         at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
         at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
         at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
         at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
         at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
         at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
         at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
         at ManagerCovid19.Controllers.HealthController.Filter(DateTime fromDate, DateTime toDate) in C:\Users\fekel\source\repos\ManagerCovid19\ManagerCovid19\Controllers\HealthController.cs:line 59
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

我做错了什么??

【问题讨论】:

  • 这更像是一个 EntityFrameworkCore 问题,它似乎并不特定于您使用 ASP.NET Core 的事实。

标签: c# sql asp.net asp.net-mvc-3 entity-framework-core


【解决方案1】:

我认为这与 EF Core 3.x 及更高版本的变化有关 -> https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.x/breaking-changes#linq-queries-are-no-longer-evaluated-on-the-client

它无法将 x = m.Sum(n => n.Member.Sector == Member.Sectors.Administrador ? 1 : 0) 表达式转换为 SQL,因此它会抛出异常(也如预期的那样)

文档说要先调用 AsEnumberable() 或 ToList(),这样才能在客户端调用。

【讨论】:

  • 谢谢...成功了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多