ado.net entity framework使用odp.net(ODAC for .net)连接oracle11g体验
标签
odp.net (ODAC for .net)
ado.net entity framework database first
winform
内容简介
小项目ado.net entity framework使用odp.net连接oracle11g体验分享。没啥技术含量,高手请绕行!
1、架构,没分层小程序而已,没必要那么麻烦。
2、edmx模型(使用向导从数据库生成)
3、程序界面截图
4、主要代码和使用到EF、odp.net的使用体验。
(1)扩展向导生成的Context对象。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DnaSecurityCodeApp { public partial class SecurityCodeEntities { /// <summary> /// 获取oracle服务器当前系统时间,select sysdate from dual; /// </summary> /// <param name="sqlCmd"></param> /// <returns></returns> public DateTime GetDbServerDateTime() { DateTime result = DateTime.Now; try { result = this.ExecuteStoreQuery<DateTime>("select sysdate from dual", new object[] { }).FirstOrDefault(); } catch (Exception ex) { throw ex; } return result; } /// <summary> /// 执行指定脚本,返回受影响的行数 /// </summary> /// <param name="sqlTxt"></param> /// <returns></returns> public int ExecuteSql(string sqlTxt) { try { return this.ExecuteStoreCommand(sqlTxt, new object[] { }); } catch (Exception ex) { return -1; throw ex; } } /// <summary> /// 返回查询结果,只能支持查询一列数据,且需要明确指定返回值的类型 /// </summary> /// <param name="sqlCmdTxt"></param> /// <returns></returns> public string GetSingleValue<T>(string sqlCmdTxt) { try { var obj = this.ExecuteStoreQuery<T>(sqlCmdTxt, new object[]{}); return obj.FirstOrDefault().ToString(); } catch (Exception ex) { return string.Empty; throw ex; } } } }
写这个类主要是使用oracle特定的sql语法获取oracle服务器信息,比如sysdate、数据库版本、字符集、序列的下一个值等。
ef使用odp.net的连接字符串:
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> </startup> <connectionStrings> <add name="SecurityCodeEntities" connectionString="metadata=res://*/SecurityCodeDb.csdl|res://*/SecurityCodeDb.ssdl|res://*/SecurityCodeDb.msl;provider=Oracle.DataAccess.Client;provider connection string="DATA SOURCE=jp2012;PASSWORD=123#dba;PERSIST SECURITY INFO=True;USER ID=JP2012"" providerName="System.Data.EntityClient" /> </connectionStrings> </configuration>
provider=Oracle.DataAccess.Client,ef会自动使用odp.net对应版本的比如Oracle.DataAccess.dll等一般为了部署程序时应该将那几个必须的dll一并打包放到主程序同一目录下。关于这个请参看园子里Oracle免Client打包的文章,一时也说不清楚。我的程序小部署时就手工装了200M多的ODAC了事。
EF使用场景(这里只有"增、改、查"没有"删"):
1)查:
string sqlSecondTxt = string.Format("SELECT R.END_ID FROM SECURITYCODE_REGION R " + "WHERE TO_CHAR(R.PRODUCTDATE,'YYYY-MM-DD') = (SELECT TO_CHAR(MAX(V.PRODUCTDATE),'YYYY-MM-DD') FROM SECURITYCODE_REGION V WHERE V.PRDFACTORYCODE = '{0}' AND V.PRDLINENO='{1}') AND " + "R.PRDFACTORYCODE = '{2}' AND R.PRDLINENO='{3}'", txtFacNo.Text.Trim(), txtPrdLineCode.Text.Trim(), txtFacNo.Text.Trim(), txtPrdLineCode.Text.Trim()); string result = oraDb.GetSingleValue<decimal>(sqlSecondTxt);
2)又查又改:
var regEntity = oraDb.SECURITYCODE_REGION.Where("it.END_ID = @end_id and it.PRDFACTORYCODE =@facNo and it.PRDLINENO = @prdLine", new ObjectParameter[]{ new ObjectParameter("end_id",beginIdentityNo), new ObjectParameter("facNo",txtFacNo.Text.Trim()), new ObjectParameter("prdLine",txtPrdLineCode.Text.Trim()) }).FirstOrDefault(); if (regEntity != null) { regEntity.END_ID = beginIdentityNo + codeCountNum; regEntity.ROWVERSIONFLAG = oraDb.GetDbServerDateTime(); oraDb.SaveChanges(); }
3)增:
#region 新增记录,起始截至先看前一次的,如果没有默认从0开始 SECURITYCODE_REGION region = new SECURITYCODE_REGION(); var seq = oraDb.GetSingleValue<decimal>("select product_reg_seq.nextval from dual"); region.IDENTITYNO = long.Parse(seq); region.PRDFACTORYCODE = txtFacNo.Text.Trim(); region.PRDLINENO = txtPrdLineCode.Text.Trim(); region.PRODUCTNO = int.Parse(txtProductNo.Text.Trim()); region.PRODUCTNAME = txtProductName.Text.Trim(); region.PRODUCTDATE = DateTime.Parse(dtProduct.Value.ToShortDateString() + " 00:00:00"); region.ROWVERSIONFLAG = DateTime.Now; region.BATCHNO = txtBatchNo.Text.Trim(); region.BEGIN_ID = beginIdentityNo; region.END_ID = beginIdentityNo + codeCountNum; oraDb.SECURITYCODE_REGION.AddObject(region); oraDb.SaveChanges(); #endregion
4)其他查询:
/// <summary> /// 按产品代码进行增量查询(模糊查询) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txtPrdCode_TextChanged(object sender, EventArgs e) { if ((txtPrdCode.Text.Trim().Length > 0) && txtPrdCode.Focused) { using (SecurityCodeEntities db = new SecurityCodeEntities()) { var list = db.ExecuteStoreQuery<SC_JP_PRODUCTINFO>(string.Format("select * from SC_JP_PRODUCTINFO t where t.product_code like '{0}%'", txtPrdCode.Text.Trim()), new object[] { }).OrderBy(p => p.PRODUCT_CODE).Take(100); gridSource.DataSource = list; } } }
这里有个插曲,EF使用like关键字,好像看msdn里面是可以的,可能是EF版本缘故吧,"PRODUCT_CODE"是number(6)整数类型,在linq to object的时候不能使用Contains()来代替like "%value%"这种。实在没辙了,PLSQL DEVELOP里面运行整数字段也是可以where like "value%"实现增量查询的啊。无奈使用上面的办法成功了。
其他类型的比如varchar2的字段是可以的:
using (SecurityCodeEntities db = new SecurityCodeEntities()) { string selVal = cbxpp.SelectedItem.ToString(); gridSource.DataSource = db.SC_JP_PRODUCTINFO. Where(p => p.PRD_BRAND.Contains(selVal)).ToList(); dataGridView.Focus(); }
另外绑定datagridview的数据源使用直接绑定项目对象(EF模型里的实体)的方式:
总结:
1)用下来EF使用ODP.NET效率还挺高,小项目使用database first方式很方便。
2)快速啊。分层啊、架构啊神马的都是浮云,小项目三下两下搞定好下班!
希望没有浪费您宝贵的时间。我也不知道写啥,有用您就看看,可别骂我啊!
作者:数据酷软件
出处:https://www.cnblogs.com/datacool/archive/2012/08/01/ODACNET2EFDEMO.html
关于作者:20年编程从业经验,持续关注MES/ERP/POS/WMS/工业自动化
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
联系方式: qq:71008973;wx:6857740733
基于人脸识别的考勤系统 地址: https://gitee.com/afeng124/viewface_attendance_ext
自己开发安卓应用框架 地址: https://gitee.com/afeng124/android-app-frame
WPOS(warehouse+pos) 后台演示地址: http://47.239.106.75:8080/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!