使用.NET MVC +EF调用oracle的存储过程

题记:

  需求如题,在网上搜索了一下,没有特别贴合我需求的资料,只好自己摸索,东拼西凑了解了一点东西慢慢尝试做了出来。

  难点:.NET是微软产品,主要支持Sql Server数据库,对于Oracle的数据库的资料比较少。

思路:

  EF框架是DataBase First ,先在数据库创建存储过程并测试能够执行。在系统中,通过调用SqlQuery方法来执行存储过程。【EF的SqlQuery使用教程

  封装一个执行存储过程的方法,

 

        #region 调用存储过程返回一个指定的TResult
        public List<TResult> RunProc<TResult>(string sql, params object[] pamrs)
        {
            return db.Database.SqlQuery<TResult>(sql, pamrs).ToList();
        }
        #endregion

 

  参数sql为执行存储过程的sql语句,在oracle数据库中为

  begin  存储过程名称(参数1,参数2,……);end;

  参数pamrs为Oracle.ManagedDataAccess.Client.OracleParameter类型的数组【OracleParameter的教程】,需要引用的dll为Oracle.ManagedDataAccess.dll,可以通过NuGet包添加。

  最后根据输出参数的值判断是否成功调用存储过程。

  PS:可以用try catch来捕获异常并输出

代码: 

        public ResultModel<object> ProExecute()
        {
            try
            {
                //参数数列
                List<OracleParameter> parameters = new List<OracleParameter>();
                //输入参数
                parameters.Add(new OracleParameter("exeno", DateTime.Now.ToString("yyyyMMddHHmmss")));
                parameters.Add(new OracleParameter("exetype", "手动"));
                //输出参数
                var para_exeid = new OracleParameter("exeid", OracleDbType.Int32);
                para_exeid.Direction = System.Data.ParameterDirection.Output;
                parameters.Add(para_exeid);
                //执行存储过程
                var list = RunProc<Charges_ExelogParameter>(@"begin  pro_charges_execute(:exeno,:exetype,:exeid);end;", parameters.ToArray());
                //获取输出参数的值
                var rowid = Convert.ToInt32(parameters[2].Value.ToString());
                if (rowid > 0)
                {
                    return new ResultModel<object>() { errcode = 0, errmsg = Lang.Filed_Common_OperSuccess };
                }
                else
                {
                    return new ResultModel<object>() { errcode = 1, errmsg = Lang.ErrMsg_Common_OperationFailed };
                }
            }catch(Exception ex)
            {
                return new ResultModel<object>() { errcode = 1, errmsg = ex.Message };
            }
        }

 

要点:

  一开始调用语句为RunProc<int>(),返回报错

数据读取器具有多个字段。多个字段对于存储过程中的EDM原语或枚举类型无效(数据读取器具有多个字段。多个字段对于EDM原语或存储过程中的枚举类型无效)

这是由于int为值类型,不与存储过程的返回的模型匹配。重新建立了一个ViewModel作为返回类型。

    public class Charges_ExelogParameter
    {
        public string exetype { get; set; }
        public string exeno { get; set; }
        public int exeid { get; set; }
    }

 

 

附记:

  顺便列出不是用EF框架时,.NET调用存储过程的方法。

这次使用的是DBHelperOra帮助类,同时也要引用Oracle.ManagedDataAccess.dll。

下面是DBHelperOra里我们需要用到的方法。

        public static void RunProcedureNoReturn(string storedProcName, IDataParameter[] parameters)
        {
            using (OracleConnection connection = new OracleConnection(connectionString))
            {
                connection.Open();
                OracleCommand command = BuildQueryCommand(connection, storedProcName, parameters);
                command.ExecuteNonQuery();
                connection.Close();
            }
        }

逻辑类似,声明参数变量后直接调用RunProcedureNoReturn去执行存储过程。

        public int UpdateTagMember(int tagid,string userid)
        {
            IDataParameter[] para = new IDataParameter[2];
            para[0] = new OracleParameter("@USERID", userid);
            para[1] = new OracleParameter("@TAGID", OracleDbType.Int32, tagid,ParameterDirection.InputOutput);
            DBHelperOra.RunProcedureNoReturn("PRO_TAGMEMBER_UPDATE", para);
            return para[1].Value.ObjToInt();
        }

 

 

参考:https://www.cnblogs.com/lizichao1991/p/6867331.html

 

posted @ 2019-02-12 17:17  奈何碧落黄泉  阅读(810)  评论(3编辑  收藏  举报