ADO.NET Entity Framework 是.Net Framework 3.5 SP1 引入的实体框架,它使开发人员可以通过对象模型(而不是逻辑/关系数据模型)专注于数据。实体框架Entity Framework使用概念层、映射层和逻辑层将逻辑数据库结构抽象化。本文http://forum.entlib.com 开源论坛小组提供。
实体数据模型(Entity Data Model)
实体框架的核心位于其模型中。实体框架支持表示数据库中的关系架构的逻辑存储模型。关系数据库通常存储数据的方式与应用程序使用数据的方式不同。通常,这会迫使开发人员按照数据库包含数据的结构检索数据。因此,开发人员通常将数据加载到更适合处理业务规则的业务实体中。在本示例中,以逻辑模型表示关系数据库的构架,业务实体表示概念模型。实体框架使用映射层在模型之间搭建了桥梁。因此,实体框架的模型中有三个处于活动状态的层:
1. 概念层(Conceptual layer) - 表示数据的概念模型,包括实体和相互关系。
2. 逻辑层(Logical layer)- 描述数据在数据库的存储模型。
3. 映射层(Mapping layer) - 在概念层和逻辑层模型之间建立映射。
这三层允许将数据从关系数据库映射到更加面向对象的业务模型。实体框架提供了使用 XML 文件定义这些层的方法。它还基于概念模型的架构生成了一系列类。可以针对这些类进行编程以直接与数据交互。这提供了抽象级别,因此开发人员可以针对概念模型而不是关系模型进行编程。
下面演示如何使用Entity Framework 构建示例程序。
首先,使用Entity Data Model Wizard创建如下NorthwindDB.edml文件。
概念模型和逻辑模型视图:
本示例程序采用Northwind 示例数据库,下面开始编写代码对Customers表进行增、删、改、查等等操作。
1.新增Customers记录
using (NorthwindEntities myDb = new NorthwindEntities())
{
Customers customer = new Customers();
Random rm = new Random();
customer.CustomerID = "A" + rm.Next(9999).ToString();
customer.CompanyName = "EntLib.com Forum";
customer.Address = "http://www.EntLib.com";
myDb.AddToCustomers(customer);
int count = myDb.SaveChanges();
txtCustomerID.Text = customer.CustomerID;
}
2.更新Customers记录
using (NorthwindEntities myDb = new NorthwindEntities())
{
var query = from customer in myDb.Customers
where customer.CustomerID == txtCustomerID.Text.Trim()
select customer;
foreach (var row in query)
{
row.CompanyName = "Updated Company Name";
}
myDb.SaveChanges();
}
3.删除Customers记录
using (NorthwindEntities myDb = new NorthwindEntities())
{
var query = from customer in myDb.Customers
where customer.CustomerID == txtCustomerID.Text.Trim()
select customer;
foreach (var row in query)
{
myDb.DeleteObject(row);
}
myDb.SaveChanges();
}
4.查询Customers,返回所有记录
using (NorthwindEntities myDb = new NorthwindEntities())
{
dataGridView1.DataSource = myDb.Customers;
}
如下的Entity Framework Demo 程序的运行界面:
本篇文章在《ADO.NET Entity Framework 入门示例向导(附Demo程序下载)》基础上,进一步演示如何使用EntityClient 新数据提供程序、对象服务(Object Services)和LINQ to Entities与概念模型交互。Entity Framework 使用概念层、映射层和逻辑层将关系数据库结构抽象化。EntityClient和Entity SQL(新语言-实体SQL)可以与概念层的实体数据模型(Entity Data Model - EDM)交互。
如下是Entity Framework 组件图:
首先,在Class Library 项目中增加ADO.NET Entity Data Model文件,具体请参考《ADO.NET Entity Framework 入门示例向导(附Demo程序下载)》。
下面分别演示如何使EntityClient、对象服务Object Services、LINQ to Entities 访问概念数据模型。
1.使用EntityClient
EntityClient 是新的.NET 数据提供程序,EntityClient使用基于文本的语言Entity SQL与概念模型通信。
EntityClient 中的类与常见的 ADO.NET 提供程序中的类相似。例如,使用 EntityCommand 对象执行 EntityClient 查询,这需要 EntityConnection 对象连接到 EDM。当 EntityClient 与 EDM 中的实体交互时,EntityClient 不返回实体的实例而返回 DbDataReader 对象中的所有结果。EntityClient 可以返回一组标准行和列,也可以通过 DbDataReader 返回更复杂的分层数据的表示形式。
示例代码:
string customerID = txtCustomerID.Text.Trim();
// Contains a reference to an Entity Data Model (EDM) and a data source connection.
using (EntityConnection cn = new EntityConnection("Name=NorthwindEntities"))
{
cn.Open();
EntityCommand cmd = cn.CreateCommand();
cmd.CommandText =
"SELECT VALUE c FROM NorthwindEntities.Customers "+
"AS c WHERE c.CustomerID = @customerID";
cmd.Parameters.AddWithValue("customerID", customerID);
DbDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (rdr.Read())
Console.WriteLine(rdr["CompanyName"].ToString());
rdr.Close();
}
示例使用 EntityClient 连接到概念模型并检索特定的客户。EntityConnection 可以接受概念层的完整连接字符串或 App.Config 文件中连接字符串的名称。连接字符串包含元数据文件(CSDL、MSL 和 SSDL 文件)列表,以及存储的专用于数据库的连接字符串信息。
如下是示例程序使用的数据库连接串:
<connectionStrings>
<add name="NorthwindEntities" connectionString=" metadata= res://NorthwindEDM/NorthwindModel.csdl|res://NorthwindEDM/NorthwindModel.ssdl|res://NorthwindEDM/NorthwindModel.msl; provider=System.Data.SqlClient;provider connection string=" Data Source=localhost; Initial Catalog=Northwind;Integrated Security=True; MultipleActiveResultSets=True""providerName="System.Data.EntityClient" />
</connectionStrings>
2.使用对象服务Object Services
与由 EDM 表示的数据进行交互的另一种方法是使用对象服务Object Services,对象服务允许直接返回对象列表。
下面的示例演示了如何使用对象服务和实体 SQL 进行查询以检索 Customers 列表:
NorthwindEntities northwindContext = new NorthwindEntities();
string customerID = txtCustomerID.Text.Trim();
ObjectQuery<Customers> query = northwindContext.CreateQuery<Customers>(
"SELECT VALUE c FROM Customers AS c WHERE c.CustomerID = @customerID",
new ObjectParameter("customerID", customerID));
foreach (Customers c in query)
Console.WriteLine(c.CustomerID + "---" + c.CompanyName);
在 EDM 中,EntityContainer 由从 ObjectContext(在本示例中为 northwindContext)继承的类表示。ObjectContext 类实施 ObjectQuery<T> 接口,从而使其可以使用实体 SQL 或 LINQ 创建查询。
CreateQuery 方法接受参数化的实体 SQL 语句,该语句定义了将检索 Customers 实体列表的查询。通过使用 foreach 语句对 ObjectQuery<Customers> 进行迭代时将执行作用于数据库的实际 SQL 语句。
3. 使用 LINQ to Entities
上述实体SQL脚本可以通过如下的LINQ to Entities 脚本实现,代码如下:
NorthwindEntities northwindContext = new NorthwindEntities();
string customerID = txtCustomerID.Text.Trim();
var query = from c in northwindContext.Customers
where c.CustomerID == customerID
select c;
foreach (Customers c in query)
Console.WriteLine(c.CustomerID + "---" + c.CompanyName);
本示例程序演示界面如下:
使用实体框架Entity Framework,开发人员可以通过对象模型(而不是逻辑/关系数据模型)专注于数据。一旦完成 EDM 的设计并将其映射到关系存储后,就可以使用 EntityClient、ObjectServices 和 LINQ 等多种技术与对象交互。
首先,根据ADO.NET Entity Data Model 向导创建EDM文件,具体可以参考《ADO.NET Entity Framework 入门示例向导(附Demo程序下载)》文章。
1. 增加New Data Source
操作步骤如下:
选择Add New Data Source,弹出Data Source Configuration Wizard 窗口,界面如下:
选择Object 作为Data Source Type,然后点击Next按钮。
在向导的下一页,展开树节点 – Data Model,显示所有的Entity 类。选择需要创建Data Source 的 Entity 类,然后点击Next 按钮。
2. 显示Data Source
选择Data 菜单 / Show Data Sources 菜单项,显示项目中的Data Sources。
3. 将上一步创建的Data Source 拖曳到Windows Form 窗体上。
默认情况下,一个新的DataGridView 控件和Navigation toolbar 控件自动添加到Windows Form窗体上。同时,也自动创建BindingSource 和Binding Navigation 控件,并且上述的两个控件与BindingSource 和Binding Navigation 控件进行了自动绑定。
界面如下:
4. 下面进一步在DataGridView 控件显示Data Source的数据。
在Windows Form 添加如下代码:
private void Form1_Load(object sender, EventArgs e)
{
NorthwindEntities northwindEntities = new NorthwindEntities();
customersBindingSource.DataSource = northwindEntities.Customers;
}
示例程序运行界面如下:
5. 编辑和保存数据
BindingSource 组件确保对DataGridView 控件的编辑更新到Entity Class。当用户完成编辑后,需要保存更新的数据到数据库中。
下一步,将 Navigation toolbar 工具栏的Save 的Enable的属性调整为True。双击Save按钮,在Save 的click 事件添加如下代码:
private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
northwindEntities.SaveChanges();
}
SaveChanges() 方法负责将Entity class 的更新保存到数据库中。