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
File a bug
Function schema name is lost when
AsSplitQuery()is applied. IfAsSplitQuery()call is removed query runs fine and returns results. If I keepAsSplitQuery()call and create database function in public schema it also works fine. But if function is defined in another schema (commonin this example) it doesn't work because produced query doesn't contain schema nameReproducible demo
Models
Context
Query
Include stack traces
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