yv9*_*89c 3 c# entity-framework entity-framework-core .net-core
我正在编写一个库,它将围绕DbContextEntity Framework Core 5+ 中的类提供新的 API。我已经有了这些新 API 的一个版本,但它需要在最终DbContext实现中进行手动干预,例如:
// Code in the library.
public static class AwesomeExtensions
{
public static ModelBuilder AddAwesomeExtensionsSupportingEntities(this ModelBuilder modelBuilder)
{
// Set up custom entities I need to make this work.
return modelBuilder;
}
}
// Code somewhere else.
public class MyBusinessDbContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// I would like to avoid doing this here.
modelBuilder.AddAwesomeExtensionsSupportingEntities();
// Business as usual (database entities).
}
}
Run Code Online (Sandbox Code Playgroud)
经过长时间的搜索,我没有在 EF Core API 中找到允许我以非侵入式方式执行此操作的扩展点。
这是我到目前为止发现的:
DbContext并重写该OnModelCreating方法,但这并不优于我现在正在做的事情。DbContextOptionsBuilder.UseModel:我认为这可能是我可以使用的东西,但增加了太多的复杂性。通过使用此 API,OnModelCreating框架将不会调用该方法。IEntityTypeConfiguration<TEntity>:我支持这个,但它还要求您有权访问该ModelBuilder实例,然后您才能使用该ModelBuilder.ApplyConfigurationsFromAssembly方法。理想情况下,我想通过DbContextOptionsBuilder注册DbContext依赖项时提供的对象来执行此操作,例如:
// Code in some application.
public void AddServices(IServiceCollection services)
{
services.AddDbContext<MyBusinessDbContext>(options =>
{
// The ideal solution.
options.UseAwesomeExtensions();
});
}
Run Code Online (Sandbox Code Playgroud)
如果我只能在ModelBuilder将 的实例提供给OnModelCreating方法之前以不需要修改DbContext实现的方式拦截该实例,那将对我有所帮助。
欢迎任何想法。
谢谢。
负责调用的 EF Core 服务使用单一方法OnModelCreating调用IModelCustomizer
Run Code Online (Sandbox Code Playgroud)public void Customize(ModelBuilder modelBuilder, DbContext context);
拦截该方法可以让您执行您需要的操作。唯一的问题是 EF Core 没有提供覆盖现有实现的简单方法。唯一可用的方法是ReplaceService全有或全无,其明显的缺点是,如果您只想执行基本实现的前/后处理,则需要知道要替换的类是哪个。当然,其他一些扩展也可以取代您的实现(最后的胜利)。
正确实现这一点需要一堆样板来注册自定义,IDbContextOptionsExtension以便能够直接操作内部的服务集合ApplyServices方法内的服务集合。如果您有兴趣,可以在其他 EF Core 扩展库(例如 LinqKit)中找到示例。
假设没有其他扩展覆盖有问题的服务,并且知道当前的默认 EF Core 实现是由ModelCustomizer一般类或RelationalModelCustomizer关系数据库类提供的(但目前没有向简单调用的基本实现添加任何内容OnModelCreating),简化的实现就是继承其中之一并用您的实现替换服务。例如类似的东西
namespace Microsoft.EntityFrameworkCore
{
using Infrastructure;
public static class AwesomeDbContextOptionsExtensions
{
public static DbContextOptionsBuilder UseAwesomeExtensions(
this DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.ReplaceService<IModelCustomizer, AwesomeModelCustomizer>();
}
}
namespace Microsoft.EntityFrameworkCore.Infrastructure
{
public class AwesomeModelCustomizer : RelationalModelCustomizer
{
public AwesomeModelCustomizer(ModelCustomizerDependencies dependencies)
: base(dependencies) { }
public override void Customize(ModelBuilder modelBuilder, DbContext context)
{
// Do something before context.OnModelCreating(modelBuilder)...
base.Customize(modelBuilder, context);
// Do something after context.OnModelCreating(modelBuilder)...
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1798 次 |
| 最近记录: |