微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

EF Core (usdig Raw Sql) 中的 System.InvalidCastException 错误,当查询不返回行时但在查询返回行时工作

如何解决EF Core (usdig Raw Sql) 中的 System.InvalidCastException 错误,当查询不返回行时但在查询返回行时工作

在 .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,Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker,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; }
}

解决方法

我无法复制这种行为。我更新并使用了以下示例代码,其中包括您在评论中提到的 def replace_function(sequence): for i in sequence: string = sequence.replace("A","-BF+AFA+FB-").replace("B","+AF-BFB-FA+") return string replace_function("AB") >>> -+AF-BFB-FA+F+AFA+F+AF-BFB-FA+-+AF-BFB-FA+ 聚合函数,该函数在 Pomelo replace_function("AB") >>> -BF+AFA+FB-+AF-BFB-FA+ 中没有问题:

GROUP_CONCAT

为了帮助您,我们需要更多信息:

  • 确切的 LINQ 查询(包括您在 FromSqlRaw() 调用中使用的确切 SQL 查询)
  • 数据库服务器类型(例如 5.0.0-alpha.2using System.Diagnostics; using System.Linq; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using MySqlConnector; using Pomelo.EntityFrameworkCore.MySql.Infrastructure; namespace IssueConsoleTemplate { public class IceCream { public int IceCreamId { get; set; } public string Name { get; set; } public string Company { get; set; } public string FullName { get; set; } } public class Context : DbContext { public virtual DbSet<IceCream> IceCreams { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var connectionString = "server=127.0.0.1;port=3306;user=root;password=;database=So65847111_GroupConcat"; optionsBuilder.UseMySql( connectionString,ServerVersion.AutoDetect(connectionString),options => options.CharSetBehavior(CharSetBehavior.NeverAppend)) .UseLoggerFactory( LoggerFactory.Create( configure => configure .AddConsole() .AddFilter(level => level >= LogLevel.Information))) .EnableSensitiveDataLogging() .EnableDetailedErrors(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<IceCream>( entity => { entity.Property(e => e.Name) .HasDefaultValue("Vanilla"); entity.HasData( new IceCream {IceCreamId = 1,Name = "Vanilla",Company = "Icecold"},new IceCream {IceCreamId = 2,Name = "Chocolate",Company = "Mr IceCream"}); }); } } internal static class Program { private static void Main(string[] args) { using var context = new Context(); context.Database.EnsureDeleted(); context.Database.EnsureCreated(); var iceCreamIdParameter = new MySqlParameter { ParameterName = "@iceCreamIdParam",MySqlDbType = MySqlDbType.Int32,Direction = System.Data.ParameterDirection.Input,Value = 42,// <-- does not exist }; var iceCreams = context.IceCreams .FromSqlRaw(@" SELECT `IceCreamId`,`Name`,`Company`,GROUP_CONCAT(`Name`,`Company` SEPARATOR ',') AS `FullName` FROM `IceCreams` WHERE `IceCreamId` = @iceCreamIdParam GROUP BY `IceCreamId`,`Company`",iceCreamIdParameter) .AsNoTracking() .ToList(); Trace.Assert(iceCreams.Count == 0); } } } )及其确切版本(例如 MySQL

(只需使用请求的信息更新 OP。)


异常提示,您返回的字段之一不包含应有的类型(或可为空性):

System.InvalidCastException:指定的强制转换无效。 在 MySqlConnector.Core.Row.GetInt32(Int32 ordinal)

所以您的查询需要一个 MariaDB,但返回的值是别的东西。 在 8.0.21 中抛出异常时让您的调试器中断并检查它尝试转换为 Int32 的值。然后检查方法的 Row.GetInt32() 参数。最后,检查与 EF Core 生成的 SQL 查询中 Int32 参数相同位置的表达式(您应该在堆栈中 ordinal 对象的 ordinal 属性中找到它,或者您可以使用 EF Core 记录它)。


除此之外,您还可以运行我发布在您服务器上的代码。它应该可以完美地工作。如果不是,那么这应该与一些意外的 MySQL 服务器设置有关。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?