【问题标题】:Using Dapper with Oracle User-Defined Types将 Dapper 与 Oracle 用户定义类型一起使用
【发布时间】:2013-04-03 07:54:52
【问题描述】:

有没有办法将 Dapper 与存储过程返回的 Oracle 用户定义类型一起使用? Dapper 似乎可以使用存储过程(请参阅Using Dapper with Oracle stored procedures which return cursors)。

var p = new OracleDynamicParameters();
p.Add("param_list", null, OracleDbType.Object, ParameterDirection.Output);
p.Add("param_reco", null, OracleDbType.Object, ParameterDirection.Output);

在我的示例中,我添加了一个 UDT 集合对象作为输出参数 (param_list)。 我正在使用Dapper – Micro ORM for Oracle and Microsoft .NET 中发布的自定义OracleDynamicParameters

我阅读 ORM 相关内容的次数越多,我就越认为 Oracle UDT 对象是一个障碍。 在这种情况下,纯 ADO.NET 和生成的 C# 实体类似乎是唯一的方法。 也许automapper.org 可能有助于将域对象映射到 UDT 对象。

【问题讨论】:

  • 目前发生了什么?它有错误吗?或者只是不更新​​输出参数?还是...?
  • 每个Query 调用都会产生一个ArgumentException (ODAC set_value)。但这可能是由于使用了经典的 ODAC 组件造成的。我已经用经典的 ODP.NET 的 Oracle.DataAccess.Client 替换了 Oracle.ManagedDataAccess.Client。托管 ODP 驱动程序仍处于测试阶段。

标签: c# .net oracle orm dapper


【解决方案1】:

研究使用 OracleCustomTypeMapping 属性和 OracleObjectMapping 属性。不记得我是从哪里得到这个想法的,但是......

public interface INullableOracleCustomType: INullable,  IOracleCustomType
    {
    }

[OracleCustomTypeMapping("<YOUR_SCHEMA_NAME>.<UDT_OBJECT_NAME>")]
    public class ParameterObject : INullableOracleCustomType
    {
        private bool objectIsNull;

        #region constructor

        public ParameterObject()
        { }

        public ParameterObject(string parameterName, string parameterValue)
        {
            this.ParameterName = parameterName;
            this.ParameterValue = parameterValue;
        }

        #endregion

        #region properties
        [OracleObjectMappingAttribute("PARAMETERNAME")]
        public string ParameterName { get; set; }

        [OracleObjectMappingAttribute("PARAMETERVALUE")]
        public string ParameterValue { get; set; }

        public static ParameterObject Null
        {
            get
            {
                ParameterObject parameterObject = new ParameterObject();
                parameterObject.objectIsNull = true;
                return parameterObject;
            }
        }

        #endregion

        #region INullable Members

        public bool IsNull
        {
            get { return objectIsNull; }
        }

        #endregion

        #region IOracleCustomType
        public void FromCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            // Convert from the Custom Type to Oracle Object
            if (!string.IsNullOrEmpty(ParameterName))
            {
                OracleUdt.SetValue(con, pUdt, "PARAMETERNAME", ParameterName);
            }
            if (!string.IsNullOrEmpty(ParameterValue))
            {
                OracleUdt.SetValue(con, pUdt, "PARAMETERVALUE", ParameterValue);
            }
        }

        public void ToCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt)
        {
            ParameterName = (string)OracleUdt.GetValue(con, pUdt, "PARAMETERNAME");
            ParameterValue = (string)OracleUdt.GetValue(con, pUdt, "PARAMETERVALUE");
        }

        #endregion
    }

示例用法...

public static OracleParameter CreateCustomTypeArrayInputParameter<T>(string name, string oracleUDTName, T value)
            where T : INullableOracleCustomType
        {
            OracleParameter parameter = new OracleParameter();
            parameter.ParameterName = name;
            parameter.OracleDbType = OracleDbType.Array;
            parameter.Direction = ParameterDirection.Input;
            parameter.UdtTypeName = oracleUDTName;
            parameter.Value = value;
            return parameter;
        }

Oracle 似乎对 ALLCAPS 中的架构/类型/对象名称很挑剔

【讨论】:

  • 我知道这是一篇很老的帖子,但我希望可以回答:如果我们不想要一个数组,而只是一个自定义的 udt 返回参数,(例如),聊天会是 OracleDbType 吗?
  • 有关 OracleDbType 枚举的文档,请参阅:docs.oracle.com/cd/E85694_01/ODPNT/…
猜你喜欢
  • 2020-05-14
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多