Linux下.NET连接MySQL数据库出错问题解决复盘

7 篇文章 0 订阅
2 篇文章 0 订阅

之前在Linux上尝试部署过WebForm系统,虽然有一些问题,但是起码可以连上数据库把系统跑起来,不过是基于SQL Server数据库,微软自己家的支持起来应该也还好。

最近呢,又有新的Task:需要部署WebService,而且数据库是MySQL。

之前可以在Linux部署部署WebForm,同为.NET Framework的WebService应该问题也不大,就分两块的验证呗:

  1. 部署工作流WebService
  2. WebService连接MySQL数据库(这里先说明下,是通过企业库封装了下,然后调用mysql.data.dll连的MySQL数据库)

结果呢,还真在第2点上出问题了,连MySQL数据库报错如下:

Activation error occured while trying to get instance of type Database, key

其实这个错误,我还是有印象的,一开始在Windows上部署同样的WebService服务,就出过这个错误,后来是在Windows上安装了MySQL驱动mysql-connector-net-6.9.9.msi解决的。

但是,在Linux上好像没有对应的驱动。。。

只能想想办法了

还是三板斧:猜测(找差异)、验证、定论

尝试找Linux下MySQL驱动

开始怀疑是由于linux下MySQL驱动导致问题的,也看了下MySQL官网下载针对.NET && Mono的驱动压缩包,里边有相关的chm说明文档,通过谷歌翻译了下,是需要通过Mono命令gacutil注册mysql.data.dll

但是问题在于,我的Linux上的Mono是通过Jexus自动安装的,不知道位置在哪,试着找到相关路径但是也没有mono --version命令,也没有gacutil命令

于是就去问之前付费加入的Linux ASP.NET技术交流群的大佬,也说了下我用的微软企业库,人家说和这个是没关系的,让我试试直接调用mysql.data.dll试试

Linux下mysql.data.dll直接连

这个也简单,写个WebForm页面,添加mysql.data.dll引用,写个连接MySQL数据库的代码就好了

然后放到Linux上运行,测试没问题

那么,很确定,是企业库搞的鬼

搞起企业库之路

基本是确定企业库的问题,那么接下来就是看到底企业库哪里导致的问题,然后尝试解决。

还好,服务器有之前的源代码,不过生成的时候,发现各种报错(各种缺dll引用,而且引用位置乱糟糟,不知道是微软就这么搞的,还是谁干的),而且位置乱也行,引用都签入啊,这个还是很有必要的,否则就是前人挖坑后人填。

缺dll那就找dll,还好找到个专门找dll的网站:

,下载,简介,描述,修复,等相关问题一站搞定_DLL之家 (dllzj.com)icon-default.png?t=M3K6http://www.dllzj.com/search.phpdll基本找到,并将相关dll放到不同的引用位置,生成算是可以了。

接下来就是看看企业库可能哪里有问题了

还真发现一个,Data下有SQLServer、Oracle的相关代码(继承Database,以便可以根据不同的数据库,创建不同的Database对象),但是没有MySQL的相关代码,于是吭哧吭哧开始照着SqlDatabase相关代码,实现MySQLDatabase相关代码。

然后,重新生成企业库dll,重新发布到linux下

满心欢喜,但是失望而归,依旧同样的问题!

调试企业库之路

没办法,只能调试企业库相关代码了。

果断卸载Windows上的mysql驱动,这样就可以还原问题进行调试了。

果然卸载了mysql驱动,熟悉的错误来了,调试起来,正好一窥企业库的真容。

一开始调试,发现也调试不出啥,而且上面加的MySQLDatabase相关类,其实没啥用【后面也可以验证下,这个后面会说】

后来想想,原有的SqlDatabase到底干啥用了,一看发现还真有料,我之前其实是没改全的,这里涉及了数据库与数据库驱动mapping,看来应该是和我要找的问题有关系

        private static DbProviderMapping GetDefaultMapping(string dbProviderName)
        {
            // try to short circuit by default name
            if (DbProviderMapping.DefaultSqlProviderName.Equals(dbProviderName))
                return defaultSqlMapping;

            if (DbProviderMapping.DefaultOracleProviderName.Equals(dbProviderName))
                return defaultOracleMapping;

            if (DbProviderMapping.DefaultMySqlProviderName.Equals(dbProviderName))
                return defaultMySqlMapping;

            // get the default based on type
            var providerFactory = DbProviderFactories.GetFactory(dbProviderName);

            if (SqlClientFactory.Instance == providerFactory)
                return defaultSqlMapping;

            if (OracleClientFactory.Instance == providerFactory)
                return defaultOracleMapping;

            if (MySqlClientFactory.Instance == providerFactory)
                return defaultOracleMapping;

            return null;
        }

继续看,发现貌似是这样,他遍历config中ConnectionString节点(即数据库连接信息),然后找是否有对应的Database对象,找到即可成功实例化

这样感觉大概思路是知道的,但是搞到22点多,还是没调试到问题在哪,这玩意代码调试一会跳到这一会跳到那,对人家这架构是傻傻搞不懂(毕竟微软这么高级货,了解需要时间与功力的)

有点想放弃了。。。

要不再试试,又有新发现!!!

        public IEnumerable<DatabaseData> Databases
        {
            get
            {
                var databaseSettings = (DatabaseSettings)configurationSource.GetSection(DatabaseSettings.SectionName);

                foreach (ConnectionStringSettings connectionString in GetConnectionStrings())
                {
                    if (IsValidProviderName(connectionString.ProviderName))
                    {
                        yield return GetDatabaseData(connectionString, databaseSettings);
                    }
                }
            }
        }

这里IsValidProviderName方法,到底搞啥了,把我的mysql给跳过去了

        private static bool IsValidProviderName(string providerName)
        {
            return DbProviderFactories.GetFactoryClasses().Rows.Find(providerName) != null;
        }

再F12没有源代码了,反编译后代码也乱乱的,那就先问问度娘看看

两个关键词搞定:

DbProviderFactories.GetFactoryClasses就是上图所示方法体内代码

DbProviderFactories.GetFactory,如上代码F12进去再进去看到的方法

通过第2个关键词查询的信息知道,要获取相关连接驱动信息,需要config配置

<system.data>
<DbProviderFactories>

链接地址:

使用DbProviderFactories.GetFactory方法需要配置数据库提供者_weixin_30570101的博客-CSDN博客icon-default.png?t=M3K6https://blog.csdn.net/weixin_30570101/article/details/97436763?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_aa&utm_relevant_index=2按照链接中说明,做好配置,Windows上没有mysql驱动的情况下,也可以通过企业库连上MySQL数据库了。

很高兴啊,这个时候快0点了,高兴的在QQ空间赶紧发了个状态。

然后一想,确定Linux上可以了吗?赶紧试了下,也可以!这个时候0点多了。

基本得出结论

确实如大佬所言,和驱动不驱动的没关系。

Windows下之前不安装驱动不可以,安装了驱动就可以,估计是安装了驱动以后,微软库会从本地去找相关驱动,如果没有安装驱动,则需要自己手动配置了。

另外,也不是所有驱动都需要config配置,应该和一开始没有MySQLDatabase类似,企业库之前只是内置了SQLserver、Oracle等,但是没有MySQL。

基本也就是这样,太细节的还没整明白。

不过起码解决问题了,确实一下子轻松了,也有好的心情搞其他事情了,睡得迟,也能睡个好觉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值