Closed guillerglez88 closed 2 years ago
@guillerglez88 You need to make sure to call UseInternalServiceProvider in either AddDbContext or OnConfiguring. For example:
public class MyContext : DbContext
{
private static readonly IServiceProvider _serviceProvider
= new ServiceCollection()
.AddEntityFrameworkSqlServer()
.AddScoped<IMigrationsSqlGenerator, CustomSqlGenerator>()
.BuildServiceProvider();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseInternalServiceProvider(_serviceProvider)
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ListenerTest;Trusted_Connection=True;");
}
or
var appServiceProivder = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.AddScoped<IMigrationsSqlGenerator, CustomSqlGenerator>()
.AddDbContext<MyContext>(
(p, b) => b.UseInMemoryDatabase().UseInternalServiceProvider(p))
.BuildServiceProvider();
The exact pattern to use depends on how you are configuring your context and whether or not you want EF to share the same service provider as the rest of your app, but hopefully you get the idea.
Is there any pitfall if I choose to use same service provider as the rest of my app? I noticed many times a new scope is created in order to provide a clean scope to EF DbContext.
I have chosen option 2, because I'm configuring services in app Stratup.cs
. It worked right as you said. Thanks!
@guillerglez88 Using the same service provider as your app should be fine. It means that your app is more tightly coupled to EF and it is possible that something you do with services for your app could impact EF, although this is unlikely.
Note to newcomers: it's now trivial to replace any service with ReplaceService in your OnConfiguring:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(@"Host=localhost;Username=test;Password=test")
.ReplaceService<IMigrationsSqlGenerator, CustomMigrationsSqlGenerator>();
What i'm trying to enable is running code in the middle of a migration in order to apply some processing in c# code, it is specially useful wen you need to consume external services or you need to migrate serialized data, E.g:
The issue
In older versions of EF (7), i used to register my custom SQL migration generator before calling
services.AddEntityFramework()
, as shown below:I discovered this could work because you use a
.TryAdd(...)
method witch attempts to register services if not registered yet. That stopped working suddenly after upgrading to EntityFrameworkCore 1.0.0.Further technical details
EF Core version: 1.0.0 Operating system: Visual Studio version: 2015