.NET Entity Framework (with Oracle ODP.NET)

一、前言

1、Entity Framework是什么?

Entity Framework是微软对ORM框架的实现。类似的实现也有其它方式,如DevExpress 的XPO(eXpress Persistant Object,非微软公司的产品),都是比较有名的。如果时间来得及,后续会比较这两个产品。下文简称EF。

2、为什么要用ORM

有数据库编程经验的人应该知道,程序中的对象模型很大程度来源于数据库中的表,且有较强的对应关系(很多时候就是一个对应一个表)。建立这种对应关系,传统的作法是:先在数据库中建表T,再在程序中编写类C,类中的属性逐个对应表中的字段。系统运行时,数据操作层从数据库中取出表记录r,一条记录去生成一个类对象o...

以上的种种过程总结起来就是:表和对象的相互关联与转化。

这里存在大量的机械化工作,是否可以由某种机制去代替这些太繁琐的工作呢?有,这就是ORM存在的意义之一。除了效率外其它的好处还有:规范、简洁、易维护...

3、在开始前,还有几个重要概念,你必须要清楚。Code Frist?Database First?Model First?

这其实是编码的几种方式,理解起来也不复杂,基本上可以按照字面意思来理解。

Database First:如果数据库表对象已经存在,EF 可以根据数据库中的表及字段,建立POCO(Plain Old CLR Object,简单理解为‘简单类’,即没有方法,仅有attribute和property的类)对象。简言之,先有(更新)数据库,再有(更新)类/对象

Model First :先建议Model,EF根据Model生成数据库。

Code First:这种方式在MVC模式中非常流行,对于数据库对象的修改完全通过代码,而非手工去操作数据库。本文中未使用这种方式,后续文章单独讲解。

.NET Entity Framework (with Oracle ODP.NET)

具体差别,在下文中体会吧。

4、目的:本文包括如何使用EF、LINQ以及使用Model-First方式生成数据库对象定义脚本。涉及Oracle数据库、VisualStudio、ODP.NET。先从已有数据库中,通过 Entity Data Model Wizard (studio中的向导)创建实体数据模型Entity Data Model (EDM),并通过三种方式来查询EDM:

a、Linq   ;   b、含Lamda 表达式的 Linq ;  c、Entity SQL

5、环境准备

a、VisualStudio 2013 和.net framework 4.5以上

b、Oracle 11g release 2 以上

c、ODAC 12c Release 3 (12.1.0.2.1) 以上,可从Oracle官网下载。ODAC中含有为visual studio准备的开发者工具插件、ODT组件,这些在你安装ODAC时就都有了。

d、本文中的数据库HR,是Oracle的示例数据库之一(除此之外还有OE、PM、IX、SH),Oracle官方的很多示例程序都基于此数据库,建议安装。可以从你的oracle安装文件中找到($ORACLE_HOME/demo/schema),Oracle官网有,读者也可自行百度,有问题可留言。如果你英文OK,也可直接浏览 https://docs.oracle.com/database/121/COMSC/installation.htm#COMSC001

e、这些文件files.zip下载备用(注意下载链接)

 二、准备工作

1、创建一个名称为EntityFramework 的控制台应用程序 

.NET Entity Framework (with Oracle ODP.NET)

2、创建实体数据模型Entity Data Model前,要用ODT创建Oracle连接

a、在Server Explorer中添加连接

.NET Entity Framework (with Oracle ODP.NET)

b、注意,这里要用ODP.NET Managed 驱动,如图

.NET Entity Framework (with Oracle ODP.NET)

.NET Entity Framework (with Oracle ODP.NET)

c、输入你的数据库连接信息,确保数据库可以正常连接。

.NET Entity Framework (with Oracle ODP.NET)

d、打开query window,复制以下脚本并执行。

.NET Entity Framework (with Oracle ODP.NET)

e、在下载文件中找到三个存储过程脚本文件:INCREASE_SALARY_BY_10UPDATE_AND_RETURN_SALARY 和 OUTPARAM,拷到Query Window 中执行。确保新添加的存储过程出现在Procedure节点中

.NET Entity Framework (with Oracle ODP.NET)

三、使用向导创建EDM

a、在项目上点击右键,选择‘Add New Item’

.NET Entity Framework (with Oracle ODP.NET)

b、在向导中选择‘EF Designer from Database’,并选择下一步

.NET Entity Framework (with Oracle ODP.NET)

c、注意选择数据库连接,选中保存敏感信息(数据库密码),并将连接设置保存在app.config中,如图:

.NET Entity Framework (with Oracle ODP.NET)

d、注意选择表对象: DEPARTMENTS 和 EMPLOYEES ,三个存储过程对象: INCREASE_SALARY_BY_10 , UPDATE_AND_RETURN_SALARY 以及 OUTPARAM 

.NET Entity Framework (with Oracle ODP.NET)

.NET Entity Framework (with Oracle ODP.NET)

四、三种方式进行EDM查询

1、使用LINQ查询

a、添加 System.Data.Entity 引用

.NET Entity Framework (with Oracle ODP.NET)

b、在Program.cs文件中,编写如下代码

.NET Entity Framework (with Oracle ODP.NET)

e、编译执行结果如下:

.NET Entity Framework (with Oracle ODP.NET)

注意,如果系统编译错误、数据连接错误,请按如下步骤检查

a、如果出现错误:Error 66 Argument 10: cannot convert from 'System.Data.Objects.ObjectParameter' to 'System.Data.Entity.Core.Objects.ObjectParameter' D:\Aziz\Aziz Project\Development\Running Development\Web\pos\pos\Model1.Context.cs 351 278 pos

问题产生的原因:你使用了Entity Framework 6 

解决办法是:在context.cs文件中,修改命名空间,如下图:

.NET Entity Framework (with Oracle ODP.NET)

以上问题,如果使用Entity Framework 5则不会出现

b、如果出现数据连接错误,则修改app.config如下:

在entityFramework配置节中,修改provider配置

<providers>
<!--<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />-->
<provider invariantName="Oracle.ManagedDataAccess.Client"
type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
</providers>

c、打开NuGet,为项目添加ODP.NET

.NET Entity Framework (with Oracle ODP.NET)

 2、通过 lambda 表达式和 存储过程映射执行LINQ查询

LINQ查询可含有Lambda表达式。Lambda表达式可作为LINQ各种标准查询方法的参数。通过将 Oracle 存储过程映射到 EDM 中的更新、插入和删除操作,可以对实体执行这些操作。

本部分将对 EMPLOYEE 实体执行一个使用 lambda 表达式的 LINQ 查询,然后映射一个存储过程以对所有选出的行执行更新操作。这将使用之前导入到 EDM 中的一个存储过程。

 a、首先,需要创建要更新的数据对象与存储过程的映射(mapping)关系。当.NET要试图更新数据时,映射的存储过程会对LINQ选出的数据行进行更行。打开HRModel.edmx,并打开Model Browser.

.NET Entity Framework (with Oracle ODP.NET)

b、在 HRModel.edmx 中,右键单击 EMPLOYEES 实体并选择 Stored Procedure Mapping

.NET Entity Framework (with Oracle ODP.NET)

c、在 Mapping Details - EMPLOYEE 窗口中,选择 <Select Update Function>,然后选择 INCREASE_SALARY_BY_10 存储过程。

.NET Entity Framework (with Oracle ODP.NET)

d、在实体和 Oracle 数据库之间建立参数数据类型映射。从下拉列表中选择 EMPLOYEE_ID 作为 ID,选择 SALARY 作为 SAL

.NET Entity Framework (with Oracle ODP.NET)

e、键入下图中高亮显示的代码,或在 Programcs.txt 中复制以 LINQ using lambda expressions -- 开头的代码块,然后粘贴到 Program.cs 中已有代码语句的后面。单击 .NET Entity Framework (with Oracle ODP.NET)(启动调试)

.NET Entity Framework (with Oracle ODP.NET)

在应用程序中,注意到 result.SALARY 设置为 18000。实际上,Entity Framework 执行的存储过程将工资增加了 10。在下一部分中,您将对这些行执行查询,以证明工资的确增加了 10。其实,实现了类似传统意义上的数据库触发器的效果。

注:在查看了第一个结果集之后,按 Enter 键继续。

.NET Entity Framework (with Oracle ODP.NET)

3、执行Entity SQL 查询

在本部分中,将查询与前一部分相同的行,来证明存储过程已成功更新这些行。将使用 Entity Framework 中的另一种查询方法 Entity SQL 进行查询。

键入下图中高亮显示的代码,或在 Programcs.txt 中复制以 Entity SQL -- 开头的代码块,然后粘贴到 Program.cs 中已有代码语句的后面。单击 .NET Entity Framework (with Oracle ODP.NET)(启动调试),查看工资增加 10 的更新结果。

注:查看输出之后,按两下 Enter 继续。

.NET Entity Framework (with Oracle ODP.NET)

.NET Entity Framework (with Oracle ODP.NET)

 五、函数导入和隐式结果集检索 | 直接插入和更新数据

通过 Entity Framework,开发人员能够定义自己的 .NET 方法来执行数据库存储过程。具体做法是在概念模型中创建函数导入,并将其映射到存储过程。本部分将定义自己的方法并映射到 Oracle 存储过程,用以执行更新。该存储过程还将使用一个隐式结果集返回修改后的数据。开发人员在 .NET 配置文件中定义结果集元数据,以便 Entity Framework 正确检索数据。

本部分介绍如何在 Entity Framework 中以编程方式修改 Oracle 数据库数据。并将对 DEPARTMENTS 表执行插入和删除操作。

1、您将使用 Visual Studio 的函数导入工具将存储过程映射到用户定义的 .NET 方法。由于存储过程返回一个隐式结果集,因此在使用该工具之前,需要通过向导在 .NET 配置文件中定义结果集元数据。在Server Explorer中找到存储过程 UPDATE_AND_RETURN_SALARY ,右键,选择 RUN .

.NET Entity Framework (with Oracle ODP.NET)

2、打开Run Procedure 窗口。界面参数保持默认,不做修改。

.NET Entity Framework (with Oracle ODP.NET)

3、存储过程执行成功。在Out Parameters中,为New_SALARY选中‘Select For Config’

.NET Entity Framework (with Oracle ODP.NET)

4、点‘Show Config’,预览出即将要添加到App.config中的配置信息,包括返回数据集、列等元数据信息;点‘AddConfig’按钮,则将预览窗口的信息添加到App.config中。

.NET Entity Framework (with Oracle ODP.NET)

5、App.config中添加上了refCursor信息

.NET Entity Framework (with Oracle ODP.NET)

6、接下来,将使用函数导入工具把一个 .NET 方法映射到 Oracle 存储过程。右键单击 HRModel.edmx 并选择 Model Browser。

7、在 Model Browser 中,依次展开 HRModel.Store 和 Stored Procedures 节点。选择 UPDATE_AND_RETURN_SALARY 存储过程。之前在创建 EDM 时导入了该存储过程

8、右键单击 UPDATE_AND_RETURN_SALARY 并选择 Add Function Import。

.NET Entity Framework (with Oracle ODP.NET)

6、在 Add Function Import 窗口中,选择 Returns a Collection Of 部分中的 Complex。存储过程所返回的结果集中仅包含两列,而不是完整定义的实体或标量值。

单击 Get Column Information。将从 .NET 配置文件中检索列信息。

7、依次点击Create New Complex Type OK 按钮

.NET Entity Framework (with Oracle ODP.NET)

在程序中将使用默认的 UPDATE_AND_RETURN_SALARY 函数名来调用此方法

8、在Program.cs文件中输入如下代码。注意,上下文件Context中已经有UPDATE_AND_RETURN_SALARY 这个方法了,调用此方法将调用映射的存储过程,并返回数据集。

.NET Entity Framework (with Oracle ODP.NET)

9、运行程序,显示人员姓名和更改后的薪资。

.NET Entity Framework (with Oracle ODP.NET)

 六、从存储过程中获传出型参数值

本部分验证如何从存储过程中获取output 型的参数值。传出型的参数只需要在.Net中显式声名并映射到存储过程的Output Parameter。这不同于以往的EF版本中的使用导入函数的方式来获取传出参数。

1、打开Program.cs文件,键入如下代码。注意,entity context 拥有方法 OUTPARAM。ObjectParameter 对象被作为OUTPARAM方法的参数,与方法的传出型参数绑定。

.NET Entity Framework (with Oracle ODP.NET)

程序运行结果如下:

.NET Entity Framework (with Oracle ODP.NET)

七、使用LINQ进行数据插入、删除操作

本部分论证如何以编码方式使用LINQ进行插入、删除等操作

1、在Program.cs中键入如下代码。注释已说明了每段代码的操作

.NET Entity Framework (with Oracle ODP.NET)

2、运行结果如下:

.NET Entity Framework (with Oracle ODP.NET)

八、Model-First

本部分将在EMPLOYEE实体添加一个属性。为了能在数据库表中添加上相应列,Visual Studio将生成Oracle 的DDL脚本。这些脚本能够在Oracle 数据库中运行并更新表。

1、在HRModel.edm中,为EMPLOYEE实体添加新属性,名称为ADDRESS

.NET Entity Framework (with Oracle ODP.NET)

.NET Entity Framework (with Oracle ODP.NET)

2、在模型浏览窗口右键点击Model,选择Properties,做如下更改:将属性Database Schema Name 改为 HR  ,将属性DDL Generation Template 设为SSDLtoOracle.tt (VS) ,将属性Database Generation Workflow 设为Generate Oracle via T4(TPT).xaml (VS)

.NET Entity Framework (with Oracle ODP.NET)

3、右键 HRModel.edmx 选择 Generate Database from Model 菜单项

.NET Entity Framework (with Oracle ODP.NET)

4、接下来的弹出窗口中点OK

.NET Entity Framework (with Oracle ODP.NET)

5、数据库向导生成了DDL脚本,这些脚本可单独保存成文件,单独运行。注意:脚本能够创建和删除数据库对象。默认地,删除脚本被注释掉了。如果你想使用,可以执行前取消注释。

.NET Entity Framework (with Oracle ODP.NET)

九、总结

本文涉及如下内容:

1、创建Oracle Connection

2、使用向导创建实体数据模型Entity Dtata Model

3、三种方式检索查询Entity Framework Data

4、映射存储过程到EDMs

5、使用函数导入功能( Entity Framework Function Imports )创建与存储过程映射的函数

6、存储过程的传出参数的检索方法

7、编码方式修改Entity Framework data

8、以Model-First方式生成DDL脚本,并修改数据库对象

 

下一篇文章,我将介绍Code First的实现方式