ADO.NET Entityframework MYSQL provider2012-01-02 博客园 WisdomQQ接触ADO.NET Entityframework有一段时间了,在实际项目的应用中有一个最大的问题就是M$没有对多种数据库提供支持,在笔者最近碰到的一个网站项目中,公司要求使用MYSQL,到处找MYSQL的EFProvider,发现Devart dotConnect还不错,提供了比较完善的解决方案,只是在自动从数据库提取物理模型中存在编码的问题,到目前还没有找到解决办法,但是Devart dotConnect是收费的,专业版得上千美刀,有Free Edition,但是不提供对EntityFramwork的支持。无奈,寻找其他的解决方案。偶然间在一份SUN的文档中有提到在未来版本中对AEF的支持,到MYSQL.com下载最新的MySql.Data.dll为5.2.5版,并没有对AEF提供支持,再到源码服务器,惊喜得看到多了一个MySql.Data.Entity项目,MySql.Data也已经到了5.3.0版。立刻下载。下载后先编译MySQL.Data,并签名程序集,MySQL.Data.Entity引用MySQL.Data,编译并签名,取得MySQL.Data.Entity的PublicKeyToken,修改MySQL.Data中类MySqlClientFactory的IServiceProvider.GetService方法相关的代码,将Provider类型指向刚才编译好的MySQL.Data.Entity程序集中的MySql.Data.MySqlClient.MySqlProviderServices类,修改后大概就像下面的样子。
private FieldInfo MySqlDbProviderServicesInstance
{
get
{
if (mySqlDbProviderServicesInstance == null)
{
//string fullName = Assembly.GetExecutingAssembly().FullName;
//fullName = fullName.Replace("MySql.Data", "MySql.Data.Entity");
string fullName = "MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity, Version=5.3.0.0, Culture=neutral, PublicKeyToken=b3fe30829fc170e4";
Type providerServicesType = Type.GetType(fullName, false);
mySqlDbProviderServicesInstance = providerServicesType.GetField("Instance",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
}
return mySqlDbProviderServicesInstance;
}
}
object IServiceProvider.GetService(Type serviceType)
{
// DbProviderServices is the only service we offer up right now
if (serviceType != DbServicesType) return null;
if (MySqlDbProviderServicesInstance == null) return null;
return MySqlDbProviderServicesInstance.GetValue(null);
}
注意PublicKeyToken的值,要和MySQL.Data.Entity程序集对应。OK,再重新编译得到MySQL.Data.dll和MySQL.Data.Entity.dll。将这两个文件安装进GAC中。接下来注册我们的provider,打开machine.config,在system.data/DbProviderFactories节点中,添加下面的元素:
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient"
description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=5.3.0.0, Culture=neutral, PublicKeyToken=c66bfea3ae91850d" />
注意这里程序集PublicKeyToken的值,要和MySQL.Data程序集的PublicKeyToken一致。这样,在我们的程序中就可以使用AEF for MySQL了,测试一下。