.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模式中非常流行,对于数据库对象的修改完全通过代码,而非手工去操作数据库。本文中未使用这种方式,后续文章单独讲解。

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

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 的控制台应用程序 

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

a、在Server Explorer中添加连接

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

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

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

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

三、使用向导创建EDM

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

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

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

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

四、三种方式进行EDM查询

1、使用LINQ查询

a、添加 System.Data.Entity 引用

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

e、编译执行结果如下:

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

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文件中,修改命名空间,如下图:

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

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

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



type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"/>

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

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

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

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

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

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

c、在 Mapping Details - EMPLOYEE 窗口中,选择