繁体   English   中英

“没有为类型‘System.Nullable`1[System.DateTime]’(参数‘property’)定义属性‘System.DateTime Date’”异常

[英]“Property 'System.DateTime Date' is not defined for type 'System.Nullable`1[System.DateTime]' (Parameter 'property')” exception

将 EF Core 更新到 5.0.1,运行测试时出现此异常

导致这种情况的方法是:

public static IQueryable<CashoutRequest> WhereTransferOrInstitutionTransferStartDate
(
    this IQueryable<CashoutRequest> cashoutRequests, 
    DateTime? date
)
{
    if (date == null) return cashoutRequests;

    var startDate = date.Value.Date;

    return cashoutRequests.Where(cashoutRequest => 
        cashoutRequest.Transfer.CreatedAt.Date >= startDate
        || 
        cashoutRequest.InstitutionTransfer.CreatedAt.Date >= startDate
    );
}

public static IQueryable<CashoutRequest> WhereTransferOrInstitutionTransferEndDate
(
    this IQueryable<CashoutRequest> cashoutRequests, 
    DateTime? date
)
{
    if (date == null) return cashoutRequests;

    var endDate = date.Value.Date;

    return cashoutRequests.Where(cashoutRequest => 
        cashoutRequest.Transfer.CreatedAt.Date <= endDate
        || 
        cashoutRequest.InstitutionTransfer.CreatedAt.Date <= endDate
    );
}

字段CreatedAt不是nullables EF Core 是否可以在运行时将它们转换为可空值?

实体:

public class CashoutRequest
{
  public long Id { get; set; }
  public long? TransferId { get; set; }
  public DateTime CreatedAt { get; set; } = DateTime.Now;
  public DateTime? ReprovedAt { get; set; }
  public DateTime? ApprovedAt { get; set; }
  public DateTime? CanceledAt { get; set; }
  public Transfer Transfer { get; set; }
  public InstitutionTransfer InstitutionTransfer { get; set; }
}

public class Transfer
{
  public long Id { get; set; }
  public DateTime CreatedAt { get; set; } = DateTime.Now;
  public DateTime? ApprovedAt { get; set; }
  public DateTime? CanceledAt { get; set; }
  public DateTime? ReprovedAt { get; set; }
}

public class InstitutionTransfer
{
    public long Id { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.Now;
    public DateTime? ApprovedAt { get; set; }
    public DateTime? CanceledAt { get; set; }
    public DateTime? ReprovedAt { get; set; }
    public long? CashoutRequestId { get; set; }

    public CashoutRequest CashoutRequest { get; set; }
}

PS.:当我删除.Date 属性时,测试成功执行

PS².: CashoutRequest.Transfer 和 CashoutRequest.InstitutionTransfer 可以是 null,不知道会不会导致报错。 但是这些方法在更新之前工作正常

堆栈跟踪:

System.ArgumentException: Property 'System.DateTime Date' is not defined for type 'System.Nullable`1[System.DateTime]' (Parameter 'property')
   at System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
   at System.Linq.Expressions.Expression.MakeMemberAccess(Expression expression, MemberInfo member)
   at System.Linq.Expressions.MemberExpression.Update(Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.VisitMember(MemberExpression memberExpression)
   at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.TranslateInternal(Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression, Boolean preserveType)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression, Boolean preserveType)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.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 api.Controllers.Employee.TransfersController.TransferList(TransferFiltersModel model) in D:\Pagcerto\API\PaymentAccount\src\api\Controllers\Employee\TransfersController.cs:line 49
   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()

Class 映射:

public static void Map(this EntityTypeBuilder<CashoutRequest> entity)
{
    entity.ToTable("SolicitacaoTransferencia", "financeiro");

    entity.Property(p => p.Id).UseIdentityColumn();
    entity.Property(p => p.CreatedAt.IsRequired();
    entity.Property(p => p.ReprovedAt);
    entity.Property(p => p.ApprovedAt);
    entity.Property(p => p.CanceledAt);
    entity.Property(p => p.TransferId);
}

public static void Map(this EntityTypeBuilder<Transfer> entity)
{
    entity.HasKey(p => p.Id);

    entity.Property(p => p.Id).UseIdentityColumn();
    entity.Property(p => p.CreatedAt).IsRequired();
    entity.Property(p => p.ApprovedAt);
    entity.Property(p => p.CanceledAt);
    entity.Property(p => p.ReprovedAt);

    entity.HasOne(p => p.CashoutRequest).WithOne(p => p.Transfer).HasForeignKey<CashoutRequest>(p => p.TransferId).OnDelete(DeleteBehavior.Restrict);
}

public static void Map(this EntityTypeBuilder<InstitutionTransfer> entity)
{
    entity.HasKey(p => p.Id);

    entity.Property(p => p.Id).HasColumnName("Id").UseIdentityColumn();
    entity.Property(p => p.CreatedAt).IsRequired();
    entity.Property(p => p.ApprovedAt);
    entity.Property(p => p.CanceledAt);
    entity.Property(p => p.ReprovedAt);
    entity.Property(p => p.CashoutRequestId);

    entity.HasOne(p => p.CashoutRequest).WithOne(p => p.InstitutionTransfer).HasForeignKey<InstitutionTransfer>(p => p.CashoutRequestId).OnDelete(DeleteBehavior.Restrict);
}

很高兴你让它工作,但就它可能发生的原因而言,我在聊天中提到这可能是由于这个重大变化 它之前可能永远无法评估 linq 表达式,但在旧版本的 EF Core 中,它会尝试获取所有行并在客户端对其进行评估(这非常昂贵。),因此。 微软最终决定取消这一点。

最好在与生产中使用的数据库非常相似的数据库上运行测试,否则无论如何它都不会真正得到全面测试。 微软的这篇文章在这一点上讲了更多。 它还提到了 memory 数据库中的一些限制。

作为一般说明,解决这些类型问题的最佳方法是记下您从哪个版本的 EF Core 升级以及升级到哪个版本。 然后,您要查看每次升级之间的所有重大更改,看看是否有任何适用。

我在 prod 上对此进行了测试,它确实有效。 所以我将 InMemoryDatabase 更改为 SQLite 并且这个测试通过了,但是另外 59 个测试失败了。 我现在会努力修复它们

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM