yv989c / BlazarTech.QueryableValues

This library allows you to efficiently compose an IEnumerable<T> in your Entity Framework Core queries when using the SQL Server database provider.
Other
93 stars 6 forks source link

EFCore InternalServiceProvider is not supported #24

Closed PatrykPlewaOfficial closed 1 year ago

PatrykPlewaOfficial commented 1 year ago

Background

QueryableValues are not working when using EFCore InternalServiceProvider due to missing service registration in the DI container.

Unable to resolve service for type 'BlazarTech.QueryableValues.IQueryableFactory'.
This is often because no database provider has been configured for this DbContext.
A provider can be configured by overriding the 'DbContext.OnConfiguring' method
or by using 'AddDbContext' on the application service provider.
If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

EF Core registration

DI registration of EF is given this way:

services.AddDbContext<TestDbContext>((provider, builder) =>
        {
            builder.UseSqlServer(connectionString, opt =>
            {
                opt.UseQueryableValues();
            });
            builder.UseInternalServiceProvider(EntityFrameworkServices.Build(provider));
        });

public static class EntityFrameworkServices
{
    private static IServiceProvider _efServices;

    public static IServiceProvider Build(IServiceProvider serviceProvider)
    {
        if (_efServices != null)
            return _efServices;

        var efServices = new ServiceCollection()
            .AddEntityFrameworkSqlServer();

        return _efServices = efServices.BuildServiceProvider();
    }
}

Test environment

.NET 6 runtime

<PackageReference Include="BlazarTech.QueryableValues.SqlServer" Version="6.5.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.5" />

Initial Investigation

Looks like the method QueryableValuesSqlServerExtension.ApplyServices is called on the instance of IServiceCollection that is not really taking part in the creation of the ServiceProvider since the instance of the ServiceProvider has already been built manually.

yv989c commented 1 year ago

Hi @PatrykPlewaOfficial , thanks for the information. I'll take a look at it when I get a chance.