Услуги Сертификаты Новости Статьи База знаний Алгоритмы Портфолио Скачать Ссылки Поиск
Услуги arrow Новости arrow Mapping: RAW Oracle type to Guid
Mapping: RAW Oracle type to Guid Версия для печати Отправить на e-mail
04.07.2014

Стандартно тип Oracle RAW(16) маппится в Guid на стороне кода C# без дополнительных преобразований.

Но, может возникнуть ситуация, когда преобразования потребуются. Например, если RAW не 16 байт, а больше, например, 36.

В данном примере приведен обработчик на примере 16 байт. Для другого размера Вам придется модифицировать код в RawType классе в методах NullSafeGet и NullSafeSet.

Шаги:

1. Нужно реализовать класс, который будет представлять в C# коде этот тип данных (в данном случае RAW(36)).

  1. public class RawType : IUserType  
  2. {  
  3.     public static string GenerateNewId()  
  4.     {  
  5.         Guid nextVal = Guid.NewGuid();  
  6.         return nextVal.ToString("N");  
  7.     }  
  8.   
  9.     private static SqlType[] types = new SqlType[] {new SqlType(DbType.Binary)};  
  10.   
  11.     public object Assemble(object cached, object owner)  
  12.     {  
  13.         return DeepCopy(cached);  
  14.     }  
  15.   
  16.     public new bool Equals(object x, object y)  
  17.     {  
  18.         return (x != null && x.Equals(y));  
  19.     }  
  20.   
  21.     public object DeepCopy(object value)  
  22.     {  
  23.         return value;  
  24.     }  
  25.   
  26.     public object Disassemble(object value)  
  27.     {  
  28.         return DeepCopy(value);  
  29.     }  
  30.   
  31.     public int GetHashCode(object x)  
  32.     {  
  33.         return x.GetHashCode();  
  34.     }  
  35.   
  36.     public bool IsMutable  
  37.     {  
  38.         get { return true; }  
  39.     }  
  40.   
  41.     public object NullSafeGet(IDataReader rs, string[] names, object owner)  
  42.     {  
  43.         string result = null;  
  44.         byte[] buffer = (byte[]) NHibernateUtil.Binary.NullSafeGet(rs, names[0]);  
  45.         if (null != buffer)  
  46.         {  
  47.             result = new Guid(buffer).ToString("N");  
  48.             Array.Clear(buffer, 0, buffer.Length);  
  49.         }  
  50.         return result;  
  51.     }  
  52.   
  53.     public void NullSafeSet(IDbCommand cmd, object value, int index)  
  54.     {  
  55.         if (null != value)  
  56.         {  
  57.             byte[] buffer = new Guid(((string) value)).ToByteArray();  
  58.             NHibernateUtil.Binary.NullSafeSet(cmd, buffer, index);  
  59.             Array.Clear(buffer, 0, buffer.Length);  
  60.         }  
  61.     }  
  62.   
  63.     public object Replace(object original, object target, object owner)  
  64.     {  
  65.         return original;  
  66.     }  
  67.   
  68.     public Type ReturnedType  
  69.     {  
  70.         get { return typeof ( Guid ); }  
  71.     }  
  72.   
  73.     public SqlType[] SqlTypes  
  74.     {  
  75.         get { return types; }  
  76.     }  
  77. }  

Скачать

2. Реализовать соглашение в коде (Convention) для Id и Property, если у Вас в БД идентификаторы и свойства имеют данный тип. По крайней мере, у меня было так.

Соглашение для Id (C# тип Guid, в Oracle тип RAW(36))

  1. public class OracleIdConvention : IIdConvention, IIdConventionAcceptance  
  2. {  
  3.     public void Accept( IAcceptanceCriteria<IIdentityInspector> criteria )  
  4.     {  
  5.         criteria.Expect( pi => IsGuid( pi ) );  
  6.     }  
  7.   
  8.     public void Apply( FluentNHibernate.Conventions.Instances.IIdentityInstance instance   
  9.     {  
  10.         instance.CustomType( typeof( RawType ) );  
  11.     }  
  12.   
  13.     private bool IsGuid( FluentNHibernate.Conventions.Inspections.IIdentityInspector pi )  
  14.     {  
  15.         return pi.Type == typeof( Guid ) || pi.Type == typeof( Guid? );  
  16.     }  
  17. }  

Скачать

Соглашение для Property (C# тип Guid, в Oracle тип RAW(36))

  1. public class OracleGuidConvention : IPropertyConvention, IPropertyConventionAcceptance  
  2. {  
  3.     /// <summary>  
  4.     /// Guarantees that this convention will only be applied to property of Guid types.  
  5.     /// </summary>  
  6.     public void Accept( IAcceptanceCriteria<FluentNHibernate.Conventions.Inspections.IPropertyInspector> criteria )  
  7.     {  
  8.         criteria.Expect( pi => IsGuid( pi ) );  
  9.     }  
  10.   
  11.     /// <summary>  
  12.     /// Specifies that Guid properties should be mapped to "RAW" (because Oracle doesn't have a Guid type).  
  13.     /// </summary>  
  14.     public void Apply( IPropertyInstance instance )  
  15.     {  
  16.         instance.CustomType( typeof( RawType ) );  
  17.     }  
  18.   
  19.     private bool IsGuid( FluentNHibernate.Conventions.Inspections.IPropertyInspector pi )  
  20.     {  
  21.         return pi.Type == typeof( Guid ) || pi.Type == typeof( Guid? );  
  22.     }  
  23. }  

Скачать

Соглашения нужно зарегистрировать в списке соглашений (Conventions.Add(...)) в момент инициализации FluentConfiguration

Последнее обновление ( 04.07.2014 )