【发布时间】:2020-12-12 05:14:14
【问题描述】:
将 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 可以为空,我不知道这是否会导致错误。但是这些方法在更新之前工作正常
堆栈跟踪:
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()
类映射:
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);
}
【问题讨论】:
-
这不是一个答案,但你能检查一下数据库是否可以为空吗?或者如果可以的话检查迁移代码...?
-
@Ergis 这些属性在迁移或数据库中都不能为空
-
您能否将完整的异常消息添加到问题中?
-
@RufusL 消息就是这样。你是说堆栈跟踪吗?
-
@RufusL 添加了堆栈跟踪