yangzhongke / Zack.EFCore.Batch

Deleting or Updating multiple records from a LINQ Query in a SQL statement without loading entities
GNU General Public License v3.0
590 stars 85 forks source link

Got ambiguous error on DeleteRangeAsync when use Npgsql as prd database and try use InMemory when we write UT/IT #94

Closed ChangyeWei closed 2 years ago

ChangyeWei commented 2 years ago

Looks like the Zack.EFCore.Batch.Npgsql_NET6 and Zack.EFCore.Batch.InMemory_NET6 can't be import together into the same project. Then we try to install Npgsql_NET6 in data access project and InMemory_NET6 only install in UT projects, but still got error in runtime when trying to resolve some of related service. Question: Is it possible that we would write our logic using Npg and test the logic in InMemory database?

ChangyeWei commented 2 years ago

Below is what we got when trying to use InMemory in UT.

System.InvalidOperationException
Unable to resolve service for type 'Microsoft.EntityFrameworkCore.Query.IRelationalParameterBasedSqlProcessorFactory'. 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.

This is what we doing the override in TestDbContext:

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseInMemoryDatabase(databaseName: "Test");
            optionsBuilder.UseBatchEF_InMemory();
        }
yangzhongke commented 2 years ago

You can use an environment variable or injected flags to check the current executing environment to execute different UserBatchEF_XXXX(); something like below: if(xxx) { optionsBuilder.UseBatchEF_InMemory(); } else { optionsBuilder.UseBatchEF_PgSQL(); }

ChangyeWei commented 2 years ago

You can use an environment variable or injected flags to check the current executing environment to execute different UserBatchEF_XXXX(); something like below: if(xxx) { optionsBuilder.UseBatchEF_InMemory(); } else { optionsBuilder.UseBatchEF_PgSQL(); }

It's not about the injection in different env. We got compile error if we install both Zack.EFCore.Batch.Npgsql_NET6 and Zack.EFCore.Batch.InMemory_NET6. image

ChangyeWei commented 2 years ago

@yangzhongke I write an example in attachment, please help to check. You will got compile error when you try to build image

You will got an runtime error while you remove the package of InMemory from consoleApp1 and try run the UT Zack.EFCore.Batch.TestInMemory.zip

yangzhongke commented 2 years ago

Please update Zack.EFCore.Batch.InMemory_NET6 to the lastest version, and then call the DeleteRangeAsync method explicitly. BatchEFExtensions.DeleteRangeAsync(ctx,x=>x.Id>5);//for other db

InMemoryBatchEFExtensions.DeleteRangeAsync(ctx, x=>x.Id>5;// for inmem