在.NET开发面向Oracle数据库的应用程序
其实这个不是一个什么新的话题。但是之前在多次项目中,总是遇到大家针对Oracle数据库的访问时,会有各种各样的问题,最基本的就是要在客户端安装各种client,版本不一样的话还有各种问题。
静下心来看看,其实也没有那么难。我这里总结一下,如何在.NET应用程序中,简单优雅地使用Oracle数据库。
第一个原则:不要依赖
最好的情况就是,程序自己就可以完成数据访问,不需要额外地安装所谓的Oracle Client,那是一个很麻烦而且痛苦的事情。
我们首先看看,如果不装任何东西,是否可以实现Oracle数据库访问?
其实,.NET本身是自带了针对Oracle数据库访问的组件的,就是下面这个System.Data.OracleClient
我们的代码如下(这是最原始的ADO.NET代码,只是做演示)
using System;
using System.Data.OracleClient;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var connectionString = "user id=system;password=password;data source=192.168.56.101:1521/orcl";
using (var connection = new OracleConnection(connectionString))
{
var cmd = connection.CreateCommand();
cmd.CommandText = "select * from sys.dba_all_tables";
connection.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader.GetString(0));
}
reader.Close();
connection.Close();
}
}
}
}
看起来应该是没有问题的,运行起来却会报错
Additional information: System.Data.OracleClient requires Oracle client software version 8.1.7 or greater.
这里的提示就是说,需要有Oracle Client。
这不是我们希望看到的结果。实际上原理上说,我们这么理解吧,可能是这个组件只是一个wrapper,它实际去操作数据库,还需要通过Oracle Client才能实现。
使用Oracle提供的组件
更好的建议就是,使用Oracle 官方提供的托管代码组件。Oracle.ManagedDataAccess.dll
只要添加了这个Nuget Package,代码几乎不需要任何改动,直接就可以复用。
using System;
using Oracle.ManagedDataAccess.Client;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var connectionString = "user id=system;password=password;data source=192.168.56.101:1521/orcl";
using (var connection = new OracleConnection(connectionString))
{
var cmd = connection.CreateCommand();
cmd.CommandText = "select * from sys.dba_all_tables";
connection.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader.GetString(0));
}
reader.Close();
connection.Close();
}
}
}
}
当然比较理想的情况是将连接字符串之类的,可以放在配置文件中去。这个很简单,这里就不说明了。
结合Entity Framework使用
Entity Framework 出来已经好多年了,几乎成了所有.NET应用程序中的标配(不管有没有用到)。现在的最新版本应该是 6.1.3 .同时,需要注意的是,以后会有一个所谓的Entity Framework Core ,而且开源了 https://github.com/aspnet/EntityFramework
回到正题,之前的代码写法其实还是比较原始的,那么如何结合Entity Framework进行Oracle数据库方面的编程呢?
首先,安装下面的这个组件:Oracle.ManagedDataAccess.EntityFramework
然后,可以使用Code first的方式编写如下代码
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace ConsoleApplication
{
public class OracleContext : DbContext
{
public OracleContext() : base("OracleDbContext")
{
}
public DbSet<Employee> Employees { get; set; }
}
[Table("EMPLOYEES", Schema = "SYSTEM")]
public class Employee
{
[Key()]
[Column("EMPLOYEEID")]
public int EmployeeID { get; set; }
[Column("FIRSTNAME")]
public string FirstName { get; set; }
[Column("LASTNAME")]
public string LastName { get; set; }
}
}
这里的代码没有什么出奇的。配置文件需要有如下的设置(一般在添加Oracle.ManagedDataAccess.EntityFramework 这个组件的时候,会自动修改配置文件)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<dataSource alias="oracle" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.101)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) " />
</dataSources>
</version>
</oracle.manageddataaccess.client>
<connectionStrings>
<add name="OracleDbContext" connectionString="user id=system;password=password;data source=oracle" providerName="Oracle.ManagedDataAccess.Client" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<publisherPolicy apply="no" />
<assemblyIdentity name="Oracle.ManagedDataAccess" publicKeyToken="89b483f429c47342" culture="neutral" />
<bindingRedirect oldVersion="4.121.0.0 - 4.65535.65535.65535" newVersion="4.121.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v13.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
后台数据库的表格设计也是很简单。
需要注意的是,经过实验,我发现目前这个Entity Framework要求所操作的表必须要有主键,而且主键必须是一个identity column(即自己绑定一个序列,实现自动增长),否则会报错
实际上后台会通过一个触发器来实现这个功能
create or replace TRIGGER EMPLOYEES_TRG
BEFORE INSERT ON EMPLOYEES
FOR EACH ROW
BEGIN
<<COLUMN_SEQUENCES>>
BEGIN
IF INSERTING AND :NEW.EMPLOYEEID IS NULL THEN
SELECT EMPLOYEES_SEQ.NEXTVAL INTO :NEW.EMPLOYEEID FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;
接下来在前端程序中就简单多了,下面是一个代码片段
var ctx = new OracleContext();
ctx.Employees.Add(new Employee() {FirstName = "ares", LastName = "chen" });
ctx.SaveChanges();
var query = ctx.Employees.ToArray();
foreach (var item in query)
{
Console.WriteLine(item);
}
需要注意的是,如果需要使用Entity Frmaework的Database first或Model first的功能,还是需要安装Oracle Client,或者准确地说应该是ODAC组件
http://www.oracle.com/technetwork/developer-tools/visual-studio/downloads/index.html
在.NET开发面向Oracle数据库的应用程序的更多相关文章
- hive表增量抽取到oracle数据库的通用程序(一)
hive表增量抽取到oracle数据库的通用程序(二) sqoop在export的时候 只能通过--export-dir参数来指定hdfs的路径.而目前的需求是需要将hive中某个表中的多个分区记录一 ...
- hive表增量抽取到oracle数据库的通用程序(二)
hive表增量抽取到oracle数据库的通用程序(一) 前一篇介绍了java程序的如何编写.使用以及引用到的依赖包.这篇接着上一篇来介绍如何在oozie中使用该java程序. 在我的业务中,分为两段: ...
- 编程开发之--Oracle数据库--存储过程在out参数中使用光标(3)
在本系列学习随笔中的第2节我们留下了2个问题,我们现在讨论在out参数中使用光标. 1.要在out参数中使用光标,我们需要申明一个包的结构,包的结构分为包头和包体,包头只负责申明,包体只负责实现.包头 ...
- 编程开发之--Oracle数据库--存储过程和存储函数(2)
上一小结我们简单介绍了存储过程和存储函数,对存储过程和存储函数有了一个基本的了解,接下来介绍在java程序中如何调用我们创建的存储过程和存储函数 1.在应用程序中调用我们的存储过程 创建一个简单的Ja ...
- 编程开发之--Oracle数据库--存储过程和存储函数(1)
1.存储过程和存储函数 描述:指存储在数据库中供所有用户程序调用的子程序叫做存储过程.存储函数 区别:存储函数可以通过return子句返回一个函数的值 (1)存储过程 语法:create [or re ...
- 编程开发之--Oracle数据库--存储过程使用动态参数绑定(3)
1.动态参数绑定,可以实现动态的执行不同的sql --创建包 create or replace PACKAGE MYPACKAGE AS type empcursor is ref cursor; ...
- Oracle数据库连接工具的使用(三)
一.PL/SQL Developer介绍 1.简介 PL/SQL Developer是一个集成开发环境,专门开发面向Oracle数据库的应用.PL/SQL也是一种程序语言,叫做过程化SQL语言(Pro ...
- 在64位Win7中使用Navicat Premium 和PL\SQL Developer连接Oracle数据库备忘
最近接手了一个项目,服务器端数据库是oracle 11g 64位.由于主要工作不是开发,也不想在自己的电脑上安装庞大的oracle数据库,因此寻思着只通过数据库管理工具连接数据库进行一些常用的查询操作 ...
- P6 EPPM手动安装指南(Oracle数据库)(一)
P6 EPPM手动安装指南(Oracle数据库) P6 EPPM Manual Installation Guide (Oracle Database) 1. 内容... 1 1.1. ...
随机推荐
- dd——留言板再加验证码功能
1.找到后台-核心-频道模型-自定义表单 2.然后点击增加新的自定义表单 diyid 这个,不管他,默认就好 自定义表单名称 这个的话,比如你要加个留言板还是投诉建议?写上去呗 数据表 这个不要碰, ...
- DNS域名服务器
DNS是用来解析域名的,IP就相当于地址一样,不知道IP就没法访问指定网络.要上PC6下载站,输入www.pc6.com, 得先问问DNS大哥www.pc6.com在哪,然后Dns告诉你后,就上去了w ...
- web图片识别
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
- IntelliJ添加Emacs编辑器
Intellij只支持emacs as a external tool: https://www.jetbrains.com/help/idea/2016.2/tutorial-using-emacs ...
- android——数据库版本升/降级问题
数据库版本升级 在开发android应用程序的时候,一般由于在我们开发的时候我们不知道以后会后什么新功能,也有可能增加业务逻辑(也就是更新),可想而知我们原来的数据库结构可能不适用已更新的应用,那么应 ...
- http长轮询&短轮询
http 协议介绍: http 协议是请求/响应范式的, 每一个 http 响应都是由一个对应的 http 请求产生的; http 协议是无状态的, 多个 http 请求之间是没有关系的. http ...
- C#基础_单例模式
控制某个类型的实例数量-唯一一个 class Program { static void Main(string[] args) { test t1 = test.GetInstance(); tes ...
- 微软开源 WCF 分布式服务框架,并入 .NET 基金会项目
微软北京时间2015.5.20 在其 .NET Foundation GitHub 开源项目页中开放了 WCF 分布式服务框架的代码.WCF突然之间成为一个热门话题,在各大网站上都有不同的报道:dot ...
- Event Store 2.0发布,带来了安全支持和测试版Projections库
Event Store 2.0版本于上周发布,它带来了安全支持允许锁定Event Store和在事件流上设置访问控制列表.其主要新特性包括: HTTP和TCP之上的身份认证,包括账户管理 测试版Pro ...
- 慎重管理SQL Server服务的登录(启动)账户和密码
今天是大年初三,先跟大家拜个年,祝大家新年快乐.今天处理了一个alwaysOn问题——辅助副本因为磁盘空间不足一直显示[未同步——可疑],在日志中可以看到数据库处于挂起状态,与主副本失去同步.原以为只 ...