我正在遵循如何设置EF Core以在Blazor&中安全工作的指南。NET核心3.1。MS文档如下:https://learn.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());
我发现了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;
}
最重要的interface IDbContextFactory<TContext>
接口在这里:
/// <summary>Factory to create new instances of <see cref="DbContext"/>.</summary>
/// <typeparam name="TContext">The type of <seealso cref="DbContext"/> to create.</typeparam>
public interface IDbContextFactory<TContext>
where TContext : DbContext
{
/// <summary>Generate a new <see cref="DbContext"/>.</summary>
/// <returns>A new instance of <see cref="TContext"/>.</returns>
TContext CreateDbContext();
}
工厂级别在这里:
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;
}
AddDbContextFactory
将在.NET Core 5中引入。请参见此处:https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-ef-core-5-0-preview-7/.
链接到的页面为您提供了自己的代码(尽管是分段的(。
您必须将AddDbContextFactory<TContext>
类和FactoryExtensions添加到您的项目中。在那里下载示例应用程序以使其完整。
当您升级到net5时,只需将其替换为库版本即可。