您现在的位置是:首页 >技术教程 >Tbase数据库通过Npgsql.EntityFrameworkCore.PostgreSQL 访问,报insufficient data left in message 错误网站首页技术教程

Tbase数据库通过Npgsql.EntityFrameworkCore.PostgreSQL 访问,报insufficient data left in message 错误

阿成blog 2025-12-22 00:01:02
简介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.pgEnumerable.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 ,建议改成 数组

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。