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

EF6 SQLite插件开发遇配置错误:默认DbConfiguration提前加载求助

EF6 + SQLite 配置错误排查与解决方案

问题背景

开发插件时采用EF6+SQLite组合,用户反馈遇到如下错误:

The default DbConfiguration instance was used before the 'SQLiteConfiguration' type was discovered

已为Context添加[DbConfigurationType(typeof(SQLiteConfiguration))]特性,但问题未解决,推测与用户同时加载其他插件有关。同时存在两个疑问:

  1. 是否需要自行实现MyProviderServices和MyConnectionFactory,还是System.Data.SQLite库已提供这些组件?
  2. 如何修改SQLiteConfiguration构造函数,是否需要保留SetProviderFactory和SetProviderServices代码?

现有代码

Context与Configuration代码

[DbConfigurationType(typeof(SQLiteConfiguration))]
public class Context : DbContext
{
    public Context() : base(
        new SQLiteConnection { ConnectionString = "some_connection_string"}, true)
    {
    }

    public DbSet<Foo> Foos{ get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var sqliteConnectionInitializer = new SqliteDropCreateDatabaseWhenModelChanges<Context>(modelBuilder);
        System.Data.Entity.Database.SetInitializer(sqliteConnectionInitializer);
    }
}

public class SQLiteConfiguration : DbConfiguration
{
    public SQLiteConfiguration()
    {
        SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
        SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
        SetProviderServices("System.Data.SQLite",
            (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
    }
}

自动生成的app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework"
                 type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                 requirePermission="false"/>
    </configSections>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a"
                                  culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1"/>
            </dependentAssembly>
        </assemblyBinding>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Data.SQLite"
                                  culture="neutral"
                                  publicKeyToken="db937bc2d44ff139"
                />
                <bindingRedirect oldVersion="0.0.0.0-1.0.117.0" newVersion="1.0.117.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
    <entityFramework>
        <providers>
            <provider invariantName="System.Data.SqlClient"
                      type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
        </providers>
    </entityFramework>
    <system.data>
        <DbProviderFactories>
            <remove invariant="System.Data.SQLite.EF6"/>
            <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6"
                 description=".NET Framework Data Provider for SQLite (Entity Framework 6)"
                 type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6"/>
            <remove invariant="System.Data.SQLite"/>
            <add name="SQLite Data Provider" invariant="System.Data.SQLite"
                 description=".NET Framework Data Provider for SQLite"
                 type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"/>
        </DbProviderFactories>
    </system.data>
</configuration>

疑问解答与修复方案

疑问1:是否需要自行实现ProviderServices和ConnectionFactory?

不需要。System.Data.SQLite.EF6库已提供现成的SQLiteProviderFactory(内含DbProviderServices实现)和SQLiteConnectionFactory,直接使用即可,无需自行编写。

疑问2:SQLiteConfiguration构造函数的修改建议

现有配置代码逻辑正确,但需确保自定义配置被EF6提前加载,避免默认配置先初始化。可做以下调整:

  1. 保持SQLiteConfiguration为public且带无参数构造函数(当前代码已满足);
  2. 可在插件加载的早期(创建Context之前)主动初始化配置:
// 插件初始化阶段执行
DbConfiguration.SetConfiguration(new SQLiteConfiguration());
  1. 必须保留SetProviderFactory和SetProviderServices代码,这是EF6识别SQLite提供程序的核心配置。

核心错误修复:解决默认配置先加载问题

错误根源是EF6在自定义配置被发现前已初始化默认配置,多插件环境下其他插件可能提前触发EF6初始化。可通过以下方案解决:

方案1:在app.config中添加SQLite提供程序配置

在entityFramework节点下补充SQLite提供程序,确保EF6启动时直接识别:

<entityFramework>
    <providers>
        <provider invariantName="System.Data.SqlClient"
                  type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
        <!-- 添加该行 -->
        <provider invariantName="System.Data.SQLite.EF6" 
                  type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
    </providers>
</entityFramework>

方案2:提前主动设置自定义配置

在插件加载的最早阶段(未创建任何Context前)执行配置设置,抢占EF6初始化时机:

// 插件初始化入口调用
DbConfiguration.SetConfiguration(new SQLiteConfiguration());

方案3:避免提前触发EF6操作

检查插件代码,确保所有EF6相关操作(如Database.Exists())都在自定义配置设置之后执行,防止提前触发默认配置初始化。

方案4:代码注册DbProviderFactory避免配置冲突

将DbProviderFactories的配置移到代码中,规避多插件间的配置覆盖问题,在SQLiteConfiguration构造函数中添加:

var factory = SQLiteProviderFactory.Instance;
if (DbProviderFactories.GetFactoryClasses().All(f => f.InvariantName != "System.Data.SQLite.EF6"))
{
    DbProviderFactories.RegisterFactory("System.Data.SQLite.EF6", factory);
}

内容的提问来源于stack exchange,提问作者emilaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:35:22