You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Entity Framework Core动态更新实体时的模型丢失问题

问题解决方案

核心原因分析

出现该问题的本质是:EF Core 默认会缓存模型实例,当调用 ReconfigureModelAsync 触发模型重新构建时,若插件配置的加载逻辑未被重复执行、或插件程序集被GC回收,就会导致新增实体无法被重新加入模型。


具体解决步骤

1. 持久化插件程序集引用,避免被回收

加载插件DLL后,必须将程序集实例存储在全局可访问的静态集合中,防止被垃圾回收器回收:

// 在AddOnService中维护静态集合
public static class AddOnService
{
    public static readonly List<Assembly> LoadedPluginAssemblies = new List<Assembly>();

    public static void LoadPlugins(string pluginPath)
    {
        var pluginFiles = Directory.GetFiles(pluginPath, "*.dll");
        foreach (var file in pluginFiles)
        {
            var assembly = Assembly.LoadFrom(file);
            LoadedPluginAssemblies.Add(assembly);
        }
    }
}

2. 修改OnModelCreating,确保每次构建模型都加载插件配置

不要仅在初始化时调用一次配置导入,而是在ApplicationDBContext的OnModelCreating方法中,每次模型构建都重新加载所有插件的实体配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    
    // 加载核心应用的实体配置
    modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDBContext).Assembly);
    
    // 加载所有插件的实体配置
    foreach (var pluginAssembly in AddOnService.LoadedPluginAssemblies)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(pluginAssembly);
    }
}

3. 验证插件配置类的可访问性

插件中实现IEntityTypeConfiguration<BitLockerVolumeKeyProtector>的类必须是public修饰符,否则EF Core的ApplyConfigurationsFromAssembly无法扫描到该配置。

4. 手动注册实体配置(自动扫描失效时备选)

若自动扫描插件配置存在问题,可通过反射手动获取并注册所有配置类:

foreach (var pluginAssembly in AddOnService.LoadedPluginAssemblies)
{
    // 获取所有实现IEntityTypeConfiguration的非抽象类
    var configTypes = pluginAssembly.GetTypes()
        .Where(t => !t.IsAbstract 
            && typeof(IEntityTypeConfiguration).IsAssignableFrom(t));
    
    foreach (var configType in configTypes)
    {
        dynamic configInstance = Activator.CreateInstance(configType);
        modelBuilder.ApplyConfiguration(configInstance);
    }
}

5. 自定义模型缓存键,触发插件更新后的模型重建

若插件会动态更新,需自定义模型缓存键,确保插件变化时EF Core自动失效旧模型:

public class PluginModelCacheKeyFactory : IModelCacheKeyFactory
{
    public object Create(DbContext context)
    {
        // 生成基于插件程序集哈希的缓存键
        var pluginHash = string.Join("-", AddOnService.LoadedPluginAssemblies
            .Select(a => a.FullName.GetHashCode().ToString()));
        return (context.GetType(), pluginHash);
    }
}

然后在DbContext服务注册时替换默认的缓存键工厂:

services.AddDbContext<ApplicationDBContext>(options =>
{
    options.UseSqlServer(yourConnectionString);
    options.ReplaceService<IModelCacheKeyFactory, PluginModelCacheKeyFactory>();
});

内容的提问来源于stack exchange,提问作者Régis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:18:18