簡體   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