Skip to content

Function schema name is lost when AsSplitQuery() is applied #34341

@llRandom

Description

@llRandom

File a bug

Function schema name is lost when AsSplitQuery() is applied. If AsSplitQuery() call is removed query runs fine and returns results. If I keep AsSplitQuery() call and create database function in public schema it also works fine. But if function is defined in another schema (common in this example) it doesn't work because produced query doesn't contain schema name

Reproducible demo

Models

    public class MatchingScore
    {
        public int Id { get; set; }
        public double MatchScore { get; set; }
    }

    public class Company
    {
        public int Id { get; set; }
        public required string Name { get; set; }
        public List<CompanyCompanyType>? CompanyTypes { get; set; }
    }

    public class CompanyType
    {
        public int Id { get; set; }
        public required string Name { get; set; }
    }

    public class CompanyCompanyType
    {
        public int CompanyTypeId { get; set; }
        public CompanyType? CompanyType { get; set; }
        public int CompanyId { get; set; }
        public Company? Company { get; set; }
    }

Context

    public class EFContext : DbContext
    {
        public IQueryable<MatchingScore> MatchingScore(int matchCompanyId, int? id1, int? id2, string json)
            => throw new NotSupportedException();

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSnakeCaseNamingConvention();
            optionsBuilder.UseNpgsql("Server=localhost;Database=SplitQueryBug;Port=5432;User Id=postgres;Password=local;Ssl Mode=Prefer;Include Error Detail=true;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Company>().ToTable("company", "company");
            modelBuilder.Entity<CompanyType>().ToTable("company_type", "company");
            modelBuilder.Entity<CompanyCompanyType>().ToTable("company_company_type", "company").HasKey(m => new { m.CompanyId, m.CompanyTypeId });
            modelBuilder.HasDbFunction(typeof(EFContext).GetMethod(nameof(MatchingScore), new[] { typeof(int), typeof(int?), typeof(int?), typeof(string) })!)
                .HasSchema("common")
                .HasName("matching_score");
        }
    }

Query

using var context = new EFContext();
var query = from company in context.Set<Company>()
            from match in context.MatchingScore(company.Id, 1, 1, "[]")
            select new
            {
                company.Id,
                company.CompanyTypes,
                match.MatchScore
            };
var rows = query.AsSplitQuery().ToList();

Include stack traces

Npgsql.PostgresException
  HResult=0x80004005
  Message=42883: function matching_score(integer, integer, integer, unknown) does not exist

POSITION: 95
  Source=Npgsql
  StackTrace:
   at Npgsql.Internal.NpgsqlConnector.<ReadMessageLong>d__233.MoveNext()
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at Npgsql.NpgsqlDataReader.<NextResult>d__52.MoveNext()
   at Npgsql.NpgsqlDataReader.<NextResult>d__52.MoveNext()
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.<ExecuteReader>d__119.MoveNext()
   at Npgsql.NpgsqlCommand.<ExecuteReader>d__119.MoveNext()
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<PopulateSplitCollection>g__InitializeReader|30_1[TCollection,TElement,TRelatedEntity](RelationalQueryContext queryContext, RelationalCommandCache relationalCommandCache, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<>c__30`3.<PopulateSplitCollection>b__30_0(ValueTuple`4 tup)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext _, TState s)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.PopulateSplitCollection[TCollection,TElement,TRelatedEntity](Int32 collectionId, RelationalQueryContext queryContext, IExecutionStrategy executionStrategy, RelationalCommandCache relationalCommandCache, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled, SplitQueryResultCoordinator resultCoordinator, Func`3 childIdentifier, IReadOnlyList`1 identifierValueComparers, Func`5 innerShaper, Action`3 relatedDataLoaders)
   at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Program.<Main>$(String[] args) in C:\Users\eugene\Projects\SplitQueryBug\Program.cs:line 15

Include provider and version information

EF Core version: 8.0.7
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 8.0.4
Target framework: .Net 8.0
Operating system: Windows 11 (Version 10.0.22631.3880)
IDE: Visual Studio 2022 17.9.3

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions