之前在Linux上尝试部署过WebForm系统,虽然有一些问题,但是起码可以连上数据库把系统跑起来,不过是基于SQL Server数据库,微软自己家的支持起来应该也还好。
最近呢,又有新的Task:需要部署WebService,而且数据库是MySQL。
之前可以在Linux部署部署WebForm,同为.NET Framework的WebService应该问题也不大,就分两块的验证呗:
- 部署工作流WebService
- 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)http://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博客https://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。
基本也就是这样,太细节的还没整明白。
不过起码解决问题了,确实一下子轻松了,也有好的心情搞其他事情了,睡得迟,也能睡个好觉。