zoukankan      html  css  js  c++  java
  • 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)快速啊。分层啊、架构啊神马的都是浮云,小项目三下两下搞定好下班!

    希望没有浪费您宝贵的时间。我也不知道写啥,有用您就看看,可别骂我啊!

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    "作者:" 数据酷软件工作室
    "出处:" http://datacool.cnblogs.com
    "专注于CMS(综合赋码系统),MES,WCS(智能仓储设备控制系统),WMS,商超,桑拿、餐饮、客房、足浴等行业收银系统的开发,15年+从业经验。因为专业,所以出色。"
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  • 相关阅读:
    scrum立会报告+燃尽图(第三周第一次)
    scrum立会报告+燃尽图(第二周第七次)
    scrum立会报告+燃尽图(第二周第六次)
    scrum立会报告+燃尽图(第二周第五次)
    scrum立会报告+燃尽图(第二周第四次)
    006_for
    005_while
    003_if_else
    002_how to use getpass
    图像旋转
  • 原文地址:https://www.cnblogs.com/datacool/p/ODACNET2EFDEMO.html
Copyright © 2011-2022 走看看