在 .Net 5 Web Api 应用程序中,我正在从 MySql 表中读取一些行(使用 Pomelo 库)。我正在使用原始 sql 查询。所以:
MySqlParameter propertyIdParam = new MySqlParameter()
{
ParameterName = "@propertyId",
MySqlDbType = MySqlDbType.Int32,
Direction = System.Data.ParameterDirection.Input,
Value = 7
};
List<PropertyRepairsDto> propertyRepairs = await _context.PropertyRepairs
.FromSqlRaw("some sql query", propertyIdParam)
.AsNoTracking()
.ToListAsync();
奇怪的是,这很好用,直到我提供一个不存在的参数(“propertyId”)——这样查询就不会返回任何行。在这种情况下,我得到以下异常:
System.InvalidCastException: Specified cast is not valid.
at MySqlConnector.Core.Row.GetInt32(Int32 ordinal) in /_/src/MySqlConnector/Core/Row.cs:line 211
at MySqlConnector.MySqlDataReader.GetInt32(Int32 ordinal) in /_/src/MySqlConnector/MySqlDataReader.cs:line 238
at lambda_method848(Closure , QueryContext , DbDataReader , Int32[] )
at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at PropWorx.API.Controllers.PropertiesController.GetPropertyRepairsAsync(Int32 id) in C:\Users\fabsr\source\repos\PropWorx.API\PropWorx.API\Controllers\PropertiesController.cs:line 194
at lambda_method479(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
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>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at PropWorx.API.Middlewares.TenantIdentifier.Invoke(HttpContext httpContext, SharedContext sharedContext) in C:\Users\fabsr\source\repos\PropWorx.API\PropWorx.API\Middlewares\TenantIdentifier.cs:line 52
at PropWorx.API.Middlewares.WebSocketsMiddleware.Invoke(HttpContext httpContext) in C:\Users\fabsr\source\repos\PropWorx.API\PropWorx.API\Middlewares\WebSocketsMiddleware.cs:line 28
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
HEADERS
=======
Connection: keep-alive
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip, deflate, br
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1ERXpSRUUwUWpFMk9VTkdOa0kyUlRJMFJEUXdNakExUTBFeE1EUkNRalpDUmtWR1JVTXhOQSJ9.eyJpc3MiOiJodHRwczovL2NvZGV4Y3JlYXRpb25zLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1OTI2YjEwYTAxZTkxZDE0MGU5OWVlNjQiLCJhdWQiOlsiaHR0cHM6Ly9wcm9wd29yeC5jby56YS9hcGkiLCJodHRwczovL2NvZGV4Y3JlYXRpb25zLmV1LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2MTAwMDkyMjQsImV4cCI6MTYxMjYwMTIyNCwiYXpwIjoiUnppNzVkU1dpcVlFYlJsVjU1N0lFd1dQYUI5Qmwzd3giLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIn0.WK2gtsbWtiz1WIkJrO56Ap8fqyyyLBs1wiKcs0KvTVTPKlzVyicf6J9S-9PMDGs1uT-gho7fVW6gLVv9XzLCulcR4x3KFrNmLSW9lvsj9fyKPMQ4Udp4A2UdfYoogRXduB62QwqRhkYGbNkI-tSGgMwF-zgClirKalpY6oKs9yMY6qr_XC4ZzTI27Pd4W9wverLtLT0-1WNlh4ynUF_xE5uvfKfh0KhBITs-KASUBMz7WcloSehNqvnkwOOdLCcWtkcbcms4LRklwEzpQvXiuCwAgjpjq980fjFjYSISjD5paqBM_rdpvG4Yz4OqI6FXtccuszbc_1WcXe7O_CSuTg
Host: localhost:5001
Referer: http://localhost:5000/api/properties/6823/repairs
User-Agent: PostmanRuntime/7.26.8
Content-Length: 2856
clientId: 273
Postman-Token: fe2fcc49-3f1b-451b-8e06-b808fa28964c
我不明白当查询返回行时它如何工作正常(因此它将数据库数据正确映射到模型字段),但是当查询不返回任何行时(我认为这应该只是导致列表零项)它会引发异常。
该异常表明将值从数据库转换为 int32 时出现问题。起初,我认为它可能是一个空值,它试图映射到我的模型中的不可为空的整数,但我的模型中的所有整数字段都是可空的。但即便如此,由于查询没有返回任何行,所以它肯定不应该是一个问题,因为没有什么可以映射?
我知道如果没有看到数据库结构、模型、查询等,很难为我提供帮助。只是查询和表都很大,我想也许有人以前遇到过这个问题,在调用查询之前一切正常不返回任何行,在这种情况下会引发 System.InvalidCastException。
这是我要映射到的模型,因为它的价值:
public class PropertyRepairsDto
{
public int? Id { get; set; }
public int? FileId { get; set; }
public string FileNum { get; set; }
public bool? IsRequired { get; set; }
public string Info { get; set; }
public bool? QuotesObtained { get; set; }
public decimal? QuoteAmount { get; set; }
public string ContractorAppointed { get; set; }
public bool? IsPaid { get; set; }
public decimal? AmountPaid { get; set; }
public DateTime? JobDate { get; set; }
public bool? PaymentRequired { get; set; }
public DateTime? PaymentDate { get; set; }
public string PaymentReference { get; set; }
public DateTime? ReportedAt { get; set; }
public int? ContractorId { get; set; }
public string Contractor { get; set; }
public bool? IsFixedByOwner { get; set; }
public DateTime? FollowUpDate { get; set; }
public string WorkOrderNumber { get; set; }
public bool? IsCompleted { get; set; }
public DateTime? CompletedDate { get; set; }
public bool? IsInvoiceReceived { get; set; }
public DateTime? InvoiceReceivedAt { get; set; }
public decimal? InvoiceAmount { get; set; }
public bool? IsInvoiceApproved { get; set; }
public DateTime? InvoiceApprovedAt { get; set; }
public string InvoiceApprovedBy { get; set; }
public bool? ChargeToTenant { get; set; }
public bool? IsReportedToOwner { get; set; }
public DateTime? ReportedToOwnerAt { get; set; }
public int? InvoiceDocId { get; set; }
public int? ReportedById { get; set; }
public string ReportedBy { get; set; }
public int? PriorityId { get; set; }
public string Priority { get; set; }
public int? QuotesRequired { get; set; }
public bool? InvoiceOwner { get; set; }
public bool? InvoiceTenant { get; set; }
public bool? IsReportSentToTenant { get; set; }
public DateTime? ReportSentToTenantAt { get; set; }
public bool? IsJobCardSentToServiceProvider { get; set; }
public int? JobCardSentToId { get; set; }
public string JobCardSentTo { get; set; }
public int? JobCardSentToServiceProviderById { get; set; }
public string JobCardSentToServiceProviderBy { get; set; }
public DateTime? JobCardSentToServiceProviderAt { get; set; }
public int? StatusId { get; set; }
public string Status { get; set; }
public int? PropertyId { get; set; }
public int? AssignedToId { get; set; }
public string AssignedTo { get; set; }
public string Comments { get; set; }
public DateTime? AddedAt { get; set; }
public DateTime? ModifiedAt { get; set; }
}