您现在的位置是:首页 >技术教程 >Tbase数据库通过Npgsql.EntityFrameworkCore.PostgreSQL 访问,报insufficient data left in message 错误网站首页技术教程
Tbase数据库通过Npgsql.EntityFrameworkCore.PostgreSQL 访问,报insufficient data left in message 错误
简介Tbase数据库通过Npgsql.EntityFrameworkCore.PostgreSQL 访问,报insufficient data left in message 错误
问题描述:
Tbase数据库通过Npgsql.EntityFrameworkCore.PostgreSQL 访问,报insufficient data left in message 错误,具体错误如下:
2025-02-08 10:55:10.801 +08:00 [EROR] 22P03: insufficient data left in message
Npgsql.PostgresException (0x80004005): 22P03: insufficient data left in message
at Npgsql.Internal.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|215_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Abp.Authorization.AuthorizationInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation)
at lambda_method5232(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__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>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Exception data:
Severity: ERROR
SqlState: 22P03
MessageText: insufficient data left in message
File: arrayfuncs.c
Line: 1672
Routine: ReadArrayBinary
通过研究发现,主要是因为 Enumerable.Contains 函数的映射问题,在efcore.pg 中 Enumerable.Contains 会映射成 id = ANY (@__Ids_0)
访问postgresql数据库时,不会存在异常。把数据库切换成tbase 则会报上述错误。
解决方案:
将 Enumerable.Contains 映射 ANY 改成 映射成 in () ,
public class ContainsTranslator : IMethodCallTranslator
{
private readonly ISqlExpressionFactory _sqlExpressionFactory;
public ContainsTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}
public SqlExpression Translate(
SqlExpression instance,
MethodInfo method,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
// 检查是否是 Contains 方法
if (method.Name == nameof(Enumerable.Contains) && arguments.Count == 2)
{
return _sqlExpressionFactory.In(arguments[1], arguments[0], false);
}
return null;
}
}
public class ContainsTranslatorProvider : NpgsqlMethodCallTranslatorProvider
{
public ContainsTranslatorProvider(
RelationalMethodCallTranslatorProviderDependencies dependencies,
IModel model,
INpgsqlSingletonOptions npgsqlSingletonOptions)
: base(dependencies, model, npgsqlSingletonOptions)
{
var npgsqlSqlExpressionFactory = (NpgsqlSqlExpressionFactory)dependencies.SqlExpressionFactory;
AddTranslators(new IMethodCallTranslator[]
{
new ContainsTranslator(npgsqlSqlExpressionFactory),
});
}
}
public class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<IMethodCallTranslatorProvider, ContainsTranslatorProvider>();
optionsBuilder.UseNpgsql("xxxxxx");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
PS: 需要注意,不能使用List.Contains ,建议改成 数组
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。





U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结