【问题标题】:How to Create a DbContextFactory in .NETCore 3.1 & Blazor如何在 .NET Core 3.1 和 Blazor 中创建 DbContext 工厂
【发布时间】:2021-01-04 06:00:43
【问题描述】:

我正在遵循有关如何设置 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());

【问题讨论】:

    标签: entity-framework .net-core blazor blazor-server-side


    【解决方案1】:

    我发现 Microsoft 文档页面在其示例 github 项目中使用了 this extension method

            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;
            }
    

    而工厂类是here:

        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);
            }
        }
    

    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;
    }
    

    【讨论】:

    • 请注意,这是针对 Blazor 优化的。如果您想在其他类型的项目中使用它,请确保将生命周期默认值更改为 Scoped,否则您的上下文将作为单例注入,这可能不是您想要的(默认值通常是作用域的)。
    • 仅供参考:如果您尝试实现它,您还需要从链接中复制 GetOptions 方法。更重要的是:当您的 DbContext 上有空的构造函数时,此代码将不会运行(AFAIK ActivatorUtilities 获取第一个上下文)。
    • 链接已损坏 :( 正在寻找 GetOptions 函数
    • 在回程中找到:private static DbContextOptions GetOptions(Action action, IServiceProvider sp = null) where TContext : DbContext { var optionsBuilder = new DbContextOptionsBuilder(); if (sp != null) { optionsBuilder.UseApplicationServiceProvider(sp); } action?.Invoke(optionsBuilder);返回选项Builder.Options; }
    【解决方案2】:

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

    【讨论】:

    • 是的,我看到并期待它,但 3.1 文档也在示例代码中描述了它。希望某处有准确的 3.1 指导。
    • 但我可以向你保证,它在当前 (3.1) 代码库中不存在。
    【解决方案3】:

    您链接到的页面为您提供了代码(尽管是零碎的),您可以自己滚动。

    您必须将AddDbContextFactory&lt;TContext&gt; 类和FactoryExtensions 添加到您的项目中。在那里下载示例应用程序以使其完整。

    当您升级到 net5 时,只需将其替换为库版本即可。

    【讨论】:

      【解决方案4】:

      标记答案上的链接坏了,但答案很好,所以我重新发布链接。

      AddDbFactory 和 GetOptions 的扩展: https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/blazor/samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Data/FactoryExtensions.cs

      【讨论】:

      猜你喜欢
      • 2020-04-10
      • 1970-01-01
      • 2021-05-15
      • 2019-07-11
      • 2020-10-27
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 2020-02-27
      相关资源
      最近更新 更多