【问题标题】:How to map a oracle decimal date into a datetime property with Nhibernate如何使用 Nhibernate 将 oracle 十进制日期映射到 datetime 属性
【发布时间】:2011-03-08 18:05:32
【问题描述】:

我正在使用 Oracle 遗留数据库。
所有日期都保存在十进制字段中,格式如下YYYYMMDD
有没有办法在日期时间(c#)中转换这种类型,也许在映射文件中?

【问题讨论】:

    标签: c# oracle nhibernate


    【解决方案1】:

    只需编写一个自定义的IEnhancedUserType 来转换字符串表示形式。

    这样它将对您的应用程序透明。

    【讨论】:

    • 谢谢 Diego,这似乎是我在寻找的东西。我会试着弄清楚它是如何工作的。
    • 我没有使用您的解决方案,因为我已经看到 IEnhancedUserType 派生自 IUserType 并且这个很简单。我已经尝试了实现并且它可以工作,即使我无法在写作模式下进行测试。我会接受你的解决方案。
    • @LeftyX:是的,实际上 IUserType 对于大多数情况来说已经足够了。
    【解决方案2】:

    最近遇到同样的问题,最后写了如下方法:

        public static DateTime? ConvertFromOracleDate(object oracleDate)
        {
            if (oracleDate == null)
                throw new ArgumentNullException("oracleDate");
    
            if (!(oracleDate is string))
                throw new ArgumentException("oracleDate");  
    
            var sDate = (string) oracleDate;
    
            if (sDate.Equals(String.Empty))
                return null;
    
            if (sDate.Length != 8)
                throw new ArgumentOutOfRangeException("oracleDate");
    
            sDate = sDate.Insert(6, "/");
            sDate = sDate.Insert(4, "/");
            var ci = new CultureInfo("en-US");
    
            return Convert.ToDateTime(sDate, ci);
        }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      最终编写了一个自定义 IUserType
      对于那些对此感兴趣的人是代码。我还没有尝试写入过程,因为我的表目前是只读的:

      public class DecimalToDateUserType : IUserType
      {
          public object NullSafeGet(IDataReader rs, string[] names, object owner)
          {
              int? result = (int)NHibernateUtil.Int32.NullSafeGet(rs, names[0]);
              if ((result != null)&&(result.Value>0))
              {
                  var sDate = result.Value.ToString();
                  sDate = sDate.Insert(6, "/").Insert(4, "/");
                  var ci = new CultureInfo("en-US");
      
                  return Convert.ToDateTime(sDate, ci);
              }
              return (DateTime.MinValue);
          }
      
          public void NullSafeSet(IDbCommand cmd, object value, int index)
          {
              if (value == null)
              {
                  NHibernateUtil.Int32.NullSafeSet(cmd, null, index);
                  return;
              }
      
              if ((DateTime)value == DateTime.MinValue)
              {
                  value = 0;
                  NHibernateUtil.Int32.NullSafeSet(cmd, value, index);
                  return;
              }
      
              int convertedValue = 0;
              int.TryParse(((DateTime)value).ToString("yyyyMMdd"), out convertedValue);
      
              value = convertedValue;
      
              NHibernateUtil.Int32.NullSafeSet(cmd, value, index);
          }
      
          public object DeepCopy(object value)
          {
              if (value == null) return null;
              return (value);
          }
      
          public object Replace(object original, object target, object owner)
          {
              return original;
          }
      
          public object Assemble(object cached, object owner)
          {
              return DeepCopy(cached);
          }
      
          public object Disassemble(object value)
          {
              return DeepCopy(value);
          }
      
          public SqlType[] SqlTypes
          {
              get
              {
                  SqlType[] types = new SqlType[1];
                  types[0] = new SqlType(DbType.Decimal);
                  return types;
              }
          }
      
          public Type ReturnedType
          {
              get { return typeof(DateTime); }
          }
      
          public bool IsMutable
          {
              get { return false; }
          }
      
          public new bool Equals(object x, object y)
          {
              if (x == null || y == null) return false;
              return x.Equals(y);
          }
      
          public int GetHashCode(object x)
          {
              return x.GetHashCode();
          }
      }
      

      【讨论】:

        【解决方案4】:

        您还可以在 SQL 查询中使用

        进行转换
        TO_DATE(TO_CHAR(semi_date_field),'yyyymmdd'))
        

        然后,您将选择具有 Oracle 数据类型 DATE 的列。 C# 无疑会将它们视为日期时间。

        问候,
        抢。

        【讨论】:

          猜你喜欢
          • 2012-04-09
          • 1970-01-01
          • 2012-02-18
          • 1970-01-01
          • 1970-01-01
          • 2023-03-04
          • 2011-10-08
          • 2013-05-15
          • 2010-10-31
          相关资源
          最近更新 更多