如何在 .NETCore 3.1 和 Blazor 中创建 DbContextFactory

Cra*_*aig 3 entity-framework .net-core blazor blazor-server-side

我正在遵循有关如何设置 EF Core 以在 Blazor 和 .NET Core 3.1 中安全工作的指南。MS 文档在这里:https : //docs.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-3.1

在说明中,建议创建一个 DbContextFactory,用于在每个服务中创建一个 dbcontext。在 Blazor 世界中一切都有意义,但代码不会编译,因为 AddDbContextFactory 不存在。如果在 .Net Core 3.1/EF Core 3 中有另一种方法可以做到这一点 - 我看不到它。

services.AddDbContextFactory<ContactContext>(opt =>
    opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db")
    .EnableSensitiveDataLogging());
Run Code Online (Sandbox Code Playgroud)

Uma*_*air 8

我发现Microsoft 文档页面在其示例 github 项目中使用的这种扩展方法

        public static IServiceCollection AddDbContextFactory<TContext>(
            this IServiceCollection collection,
            Action<DbContextOptionsBuilder> optionsAction = null,
            ServiceLifetime contextAndOptionsLifetime = ServiceLifetime.Singleton)
            where TContext : DbContext
        {
            // instantiate with the correctly scoped provider
            collection.Add(new ServiceDescriptor(
                typeof(IDbContextFactory<TContext>),
                sp => new DbContextFactory<TContext>(sp),
                contextAndOptionsLifetime));

            // dynamically run the builder on each request
            collection.Add(new ServiceDescriptor(
                typeof(DbContextOptions<TContext>),
                sp => GetOptions<TContext>(optionsAction, sp),
                contextAndOptionsLifetime));

            return collection;
        }
Run Code Online (Sandbox Code Playgroud)

工厂类在这里

    public class DbContextFactory<TContext> 
        : IDbContextFactory<TContext> where TContext : DbContext
    {
        private readonly IServiceProvider provider;

        public DbContextFactory(IServiceProvider provider)
        {
            this.provider = provider;
        }

        public TContext CreateDbContext()
        {
            if (provider == null)
            {
                throw new InvalidOperationException(
                    $"You must configure an instance of IServiceProvider");
            }

            return ActivatorUtilities.CreateInstance<TContext>(provider);
        }
    }
Run Code Online (Sandbox Code Playgroud)

GetOptions 方法:

private static DbContextOptions<TContext> 
    GetOptions<TContext>(Action<DbContextOptionsBuilder> action,
    IServiceProvider sp = null) where TContext: DbContext 
{
    var optionsBuilder = new DbContextOptionsBuilder < TContext > ();
    if (sp != null) 
    {
        optionsBuilder.UseApplicationServiceProvider(sp);
    }
    action?.Invoke(optionsBuilder);
    return optionsBuilder.Options;
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*res 5

AddDbContextFactory将在.NET Core 5中引入。请参见此处: https: //devblogs.microsoft.com/dotnet/announcing-entity-framework-core-ef-core-5-0-preview-7/