[EF]让Entity framework支持多数据库

让Entity framework支持多数据库

罗朝辉 (http://kesalin.cnblogs.com/)

本文遵循“署名-非商业用途-保持一致”创作公用协议
 

EF对Sql Server的支持非常好,无论是Code First,还是 Model First 还是 Database First 都支持的很好,但是对非微软系数据库的支持就不那么友好了,现在唯一能保证的是对大部分数据库的 Database First 支持的很好。所以在这里,我们让 Entity framework 支持多数据库实现的思路就是基于 Database First 的。首先在各数据库中创建好数据库表(这里有很多讲究的地府,字段类型必须一致,可以使用Power Designer工具来简化手工劳动),再基于某一数据库生成概念模型,存储模型以及映射关系,然后拷贝生成的存储模型文件并修改,使之能与其他数据库匹配起来,从而获得对多数据库的支持。

本示例演示了对Sql Server 2008和MySQL 5.5两种书库的支持,使用的 MySQL Connector Net 6.3.5。请参考前文安装相关的软件。下面讲述具体步骤:

1,分别在 Sql Server 2008 和 MySQL 5.5 建立数据库 school及表 student(推荐使用小写,MySQL默认使用小写),student表只包含三个字段:Id(主键),Name 和 Age。请注意两个表的数据类型必须完全一致!

Sql Server 2008表:

MySql 表:

 

2,然后分别在两个表中插入不同的测试数据,也可以在代码中写插入数据,这里为了简化,直接使用数据库管理工具插入测试数据。

3,新建C#控制台程序 EFMutilpleDatabase:

 

4,右击项目名,向其中添加类型为ADO.NET Entity Data Model的新Item:StudentModel.edmx:

选择从数据库产生:

然后新建 Connection,首先我们使用 MySQL数据库,设置连接到MySQL的Connection,数据库表选择 school,这样向导就会自动为我们生成概念模型,存储模型以及映射关系,connection string等:

选择需要用到的数据库表:

 

5,至此向导工作完成,我们先来看看向导为我们生成的文件:

App.Config:数据库连接相关的配置;

StudentModel.edmx:概念模型,存储模型,映射关系等都自动生成在该文件中;

StudentModel.Designer.cs:自动生成的代码,通过这些自动生成的数据对象类,我们就可以直接操作数据库。

 

6,为了方便后面支持多数据库,我们现在在App.Config文件中修改默认 connection string的名字为:schoolEntitiesMySQL。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="schoolEntitiesMySQL" connectionString="metadata=res://*/StudentModel.csdl|res://*/StudentModel.ssdl|res://*/StudentModel.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=localhost;User Id=root;password=yourpwd;Persist Security Info=True;database=school&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>


7,下面我们来编写测试与MySQL的连接的代码。相工程中添加 reference:System.Configuration,然后修改 Program.cs为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Objects;
using System.Configuration;

namespace EFMultipleDatabase
{
class Program
{
private static void ProcessDatabase(string connectionStringName)
{
string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
using (var queryContext = new schoolEntities(connectionString))
{
Console.WriteLine(">> All Student:");

queryContext.Connection.Open();

// Query
//
using (var transaction = queryContext.Connection.BeginTransaction())
{
var people = from p in queryContext.student orderby p.Age select p;
foreach (var p in people)
{
Console.WriteLine(" {0}, Age: {1}", p.Name, p.Age);
}

transaction.Commit();
}

queryContext.Dispose();
}
}

static void Main(string[] args)
{
Console.WriteLine(" ========MySQL=====");
ProcessDatabase("schoolEntitiesMySQL");

Console.ReadLine();
}
}
}

在上面的代码中,我们是根据读取 App.Config 中的 connection string 配置来决定连接到哪一个数据库的,这样的设计方便我们添加与其他数据库连接配置,以支持多种数据库。

8,下面我们来让程序支持 Sql Server 2008。首先,需要手动创建存储模型文件,在项目中新建名为StudentModel.SqlServer.ssdl 的xml文件。然后右击StudentModel.edmx选择 Open With XML(Text) Editor,将<!-- SSDL content -->之后介于 <edmx:StorageModels> … </edmx:StorageModels>之间的内容拷贝至新建的StudentModel.SqlServer.ssdl文件中,这样StudentModel.SqlServer.ssdl的内容应该如下:

<?xml version="1.0" encoding="utf-8" ?>
<Schema Namespace="schoolModel.Store" Alias="Self" Provider="MySql.Data.MySqlClient" ProviderManifestToken="5.1" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
<EntityContainer Name="schoolModelStoreContainer">
<EntitySet Name="student" EntityType="schoolModel.Store.student" store:Type="Tables" Schema="school" />
</EntityContainer>
<EntityType Name="student">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="varchar" MaxLength="45" />
<Property Name="Age" Type="umediumint" />
</EntityType>
</Schema>


9,紧接着我们来修改 StudentModel.SqlServer.ssdl 存储模型文件,使之能与匹配Sql Server 2008数据库表。首先我们需要将 Provider 和 ProviderManifestToken修改为:

Provider="System.Data.SqlClient" ProviderManifestToken="2008"

这表示该存储模型是基于 Sql Server 2008 数据库的。然后将各个字段的 Type 修改为Sql Server 2008支持的数据类型(MySQL使用的数据类型肯定不会与Sql Server 2008完全相同),并将该存储模型放到输出目录下,修改该文件的属性 Copy to Output Directory 为 Copy Always。。修改之后的内容应如下:

<?xml version="1.0" encoding="utf-8" ?>
<Schema Namespace="schoolModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
<EntityContainer Name="schoolModelStoreContainer">
<EntitySet Name="student" EntityType="schoolModel.Store.student" store:Type="Tables" Schema="dbo" />
</EntityContainer>
<EntityType Name="student">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false"/>
<Property Name="Name" Type="nchar" MaxLength="45" />
<Property Name="Age" Type="int" />
</EntityType>
</Schema>


10,这样我们就完成了对存储模型的修改,下面我们来在App.config中增加对Sql Server 2008数据库的连接 string。以下是修改之后的App.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="schoolEntitiesMySQL" connectionString="metadata=res://*/StudentModel.csdl|res://*/StudentModel.ssdl|res://*/StudentModel.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=localhost;User Id=root;password=yourpwd;Persist Security Info=True;database=school&quot;" providerName="System.Data.EntityClient" />
<add name="schoolEntitiesSqlServer" connectionString="metadata=res://*/StudentModel.csdl|StudentModel.SqlServer.ssdl|res://*/StudentModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=school;persist security info=True;user id=sa;password=
yourpwd
;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>


11,至此配置工作完成,我们只需在 main()中调用如下语句即可测试与Sql Server 2008数据库的连接:

        static void Main(string[] args)
{
Console.WriteLine(" ========MySQL=====");
ProcessDatabase("schoolEntitiesMySQL");

Console.WriteLine(" ========SQL Server 2008=====");
ProcessDatabase("schoolEntitiesSqlServer");

Console.ReadLine();
}

编译运行,结果如下:

 

总结:

上面的过程是先生成一致的数据库表,然后通过某种数据库生成概念模型,存储模型以及映射关系,然后拷贝并修改存储模型,使之与其他数据库匹配,从而完成对多数据库的支持。

posted @ 2012-03-20 19:52  飘飘白云  阅读(10655)  评论(6编辑  收藏  举报
本博客遵循 Creative Commons License “署名-非商业用途-保持一致”创作共用协议。 与我联系