EF6与Mysql疑难问题记录
这几天公司架构调整,新的迭代后端使用了ABP框架与CodeFirst模式,执行过程中遇到了一个非必现很难定位的问题,特此记录。
现象
在程序访问MySql数据库时报了异常
System.InvalidOperationException: The default DbConfiguration instance was used by the Entity Framework before the 'MySqlEFConfiguration' type was discovered. An instance of 'MySqlEFConfiguration' must be set at application start before using any Entity Framework features or must be registered in the application's config file.
在StackOverflow上找了很多解决方案,都找不到可靠的原因分析,折腾许久终于在官方文档上找到了答案。
原因
先来看下官方文档的一段解释:
(https://msdn.microsoft.com/en-us/data/jj680699#Moving)
There are some situations where configuration may be needed before any DbContext type has been used. Examples of this include:
- Using DbModelBuilder to build a model without a context
- Using some other framework/utility code that utilizes a DbContext where that context is used before your application context is used
In such situations EF is unable to discover the configuration automatically and you must instead do one of the following:
- Set the DbConfiguration type in the config file, as described in the Moving DbConfiguration section above
- Call the static DbConfiguration.SetConfiguration method during application startup
在括号内给出的官方文档地址中包含了两种指定DbContext配置的方式:
一,Config节点
二,DbConfigurationType特性标注在DbContext上
我们选择的是第二种方式,即指定类型后自动配置的方式。代码片段如下:
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))] public class SHMedicalRecordDbContext : AbpDbContext { ...... }
这在独立项目中是毫无问题的,但混入以前的项目就出现了开题所报的错误,问题如官方那段解释中某些不会自动配置的情况之二:某些框架或通用代码在程序调用DbContext之前就使用了它。
怎么理解这个问题,我们项目组的情况是:
遗留系统也用了EF6,新迭代所开发的系统需要嵌入老系统来使用,那么在老系统中就存在了两个DbContext,如果新系统的DbContext先被初始化,那程序不会有问题。
若遗留系统的Context先初始化,就符合了官方描述的情况之二,所以出现了异常。(新系统的初始化采用的多线程启动,所以前后顺序每次启动服务都不一样)
解决方法
解决方法也在刚才那段文字的下面,采用Config或者静态初始化的方式显式指定DbConfiguration,然后我在Config的EF节点中添加了指定,代码片段如下:
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6"> .......
问题解决。
留点东西方便后来踩坑的人。
另,EF+MySql做CodeFirest相性实在不太好(Oracle也差不多),自动迁移时各种水土不服,有条件的公司还是建议上MsSql。