2010-10-06 33 views
1

我有一個Oracle 11g中的6個表的數據庫(我無法修改)。所有表都有一個用於ID的OID人工列,其類型爲RAW(16)。數據庫管理員回答我說他們是原始數據,而不是整數,因爲這樣ID在所有六張表中都是唯一的 - 我們必須保證這一點。在NHibernate和Oracle中實現hilo(或seqhilo)

我正在開發用戶界面在C#和數據層我(嘗試)使用NHibernate。我怎樣才能以這種必需品的方式實現ID生成器?

非常感謝,

佩德羅Dusso

我的地圖是:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class name="MetaManager.Data.Job,MetaManager.Data" table="JOB" lazy="true"> 
    <id name="Oid" column="OID" type="Guid"> 
     <generator class="guid.comb" /> 
    </id> 
    <property name="JobId" type="Decimal"> 
     <column name="JOB_ID" length="10" sql-type="number" not-null="true" /> 
    </property> 
    <bag name="EtlProcesses" inverse="true" cascade="all-delete-orphan"> 
    <key column="JOB_ID"/> 
     <one-to-many class="MetaManager.Data.EtlProcess,MetaManager.Data"/> 
    </bag> 
    </class> 
</hibernate-mapping> 

我的類代碼:

namespace MetaManager.Data 
{ 
    public class Job 
    { 
     public virtual Guid Oid { get; set; } 
     public virtual decimal JobId { get; set; } 
     private IList<EtlProcess> _EtlProcesses; 
     public virtual IList<EtlProcess> EtlProcesses 
     { 
      get 
      { 
       if (_EtlProcesses == null) 
        _EtlProcesses = new List<EtlProcess>(); 
       return _EtlProcesses; 
      } 
      set 
      { 
       _EtlProcesses = value; 
      } 
     } 
    } 
} 

我創建一個作業對象和他們試圖將其保存在數據庫中。漁獲嘗試

Job job = new Job(1, "Test Job", DateTime.Now, DateTime.MaxValue, "A", "Dusso"); 

Guid retVal; 
ITransaction transaction = null; 
try 
{ 
    transaction = Session.BeginTransaction(); 
    Session.SaveOrUpdate(job); 

    if (transaction != null && transaction.IsActive) 
     transaction.Commit(); //the exception is trow here! 
    else 
     Session.Flush(); 
     retVal = job.Oid; 
} 
catch(Exception ex) 
{...} 

完整的例外是:

{System.InvalidCastException:無法將參數值從一個GUID轉換爲一個byte []。 ---> System.InvalidCastException:對象必須實現IConvertible。 在System.Convert.ChangeType(對象值,類型conversionType,的IFormatProvider提供商) 在System.Data.OracleClient.OracleParameter.CoerceValue(對象值,元類型destinationType) ---內部異常堆棧跟蹤的結尾--- 在System.Data.OracleClient.OracleParameter.CoerceValue(對象值,MetaType目標類型) at System.Data.OracleClient.OracleParameter.SetCoercedValueInternal(Object value,MetaType metaType) at System.Data.OracleClient.OracleParameterBinding.PrepareForBind(OracleConnection connection,Int32 & offset) at System.Data.OracleClient.OracleCommand.Execute(OciStatementHandle statementHandle,CommandBehavior behavior,Boolean needRowid,OciRowidDescriptor & rowidDescriptor,ArrayLis噸& resultParameterOrdinals) 在System.Data.OracleClient.OracleCommand.ExecuteNonQueryInternal(布爾needRowid,OciRowidDescriptor & rowidDescriptor) 在System.Data.OracleClient.OracleCommand.ExecuteNonQuery() 在NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand的CMD) NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id,Object [] fields,Boolean [] notNull,Int32 j,SqlCommandInfo sql,Object obj,ISessionImplementor session) 在NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id,Object [] fields,Object obj,ISessionImplementor session) at NHibernate.Action.EntityInsertAction.Execut E() 在NHibernate.Engine.ActionQueue.Execute(IExecutable可執行文件) 在NHibernate.Engine.ActionQueue.ExecuteActions(IList的列表) 在NHibernate.Engine.ActionQueue.ExecuteActions() 在NHibernate.Event.Default.AbstractFlushingEventListener。 PerformExecutions(IEventSource會議) 在NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent事件) 在NHibernate.Impl.SessionImpl.Flush() 在NHibernate.Transaction.AdoTransaction.Commit() 在MetaManager.Data.Services。 JobDataControl。保存(作業作業)在C:\ Users \ Pedro_Dusso \ documents \ visual studio 2010 \ Projects \ MetaManager \ MetaManager.Data \ Services \ JobDataControl.cs:line 45}

真誠地,我不明白你的第一個可疑。在數據庫中,我有一個JOB表和一個ETL_PROCESS表。他們的關係像1:n,一個JOB可以有很多etl過程。

PS:我加入了我的nhibernate配置,可能有幫助。使用ODP

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory> 
     <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> 
     <property name="dialect">NHibernate.Dialect.Oracle9Dialect</property> 
     <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property> 
     <property name="connection.connection_string_name">MetaManager</property> 
     <mapping assembly="MetaManager.Data"/> 
    </session-factory> 
    </hibernate-configuration> 

錯誤: {NHibernate.HibernateException:無法創建NHibernate.Driver.OracleDataClientDriver驅動程序。 ---> System.Reflection.TargetInvocationException:調用的目標引發了異常。 ---> NHibernate.HibernateException:無法找到程序集Oracle.DataAccess中的IDbCommand和IDbConnection實現。確保程序集Oracle.DataAccess位於應用程序目錄或全局程序集緩存中。如果程序集位於GAC中,請使用應用程序配置文件中的元素指定程序集的全名。 at NHibernate.Driver.ReflectionBasedDriver..ctor(String driverAssemblyName,String connectionTypeName,String commandTypeName) at NHibernate.Driver.OracleDataClientDriver..ctor() ---內部異常堆棧跟蹤結束--- at System.RuntimeTypeHandle .CreateInstance(RuntimeType類型,布爾publicOnly,布爾NOCHECK,布爾& canBeCached,RuntimeMethodHandleInternal &構造函數,布爾& bNeedSecurityCheck) 在System.RuntimeType.CreateInstanceSlow(布爾publicOnly,布爾skipCheckThis,布爾fillCache) 在System.RuntimeType.CreateInstanceDefaultCtor(布爾publicOnly,布爾skipVisibilityChecks,布爾skipCheckThis,布爾fillCache) 在System.Activator.CreateInsta NCE(類型類型,布爾非公開) 在System.Activator.CreateInstance(類型類型) 在NHibernate.Connection.ConnectionProvider.ConfigureDriver(IDictionary的2 settings) --- End of inner exception stack trace --- at NHibernate.Connection.ConnectionProvider.ConfigureDriver(IDictionary 2設置) 在NHibernate.Connection.ConnectionProvider.Configure(IDictionary的2 settings) at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(IDictionary 2個設置) NHibernate.Cfg.SettingsFactory.BuildSettings(IDictionary`2 properties) at NHibernate.Cfg.Configuration.BuildSettings() at NHibernate.Cfg.Configuration.BuildSessionFactory() at MetaManager.Data.SessionProvider.get_Session()in C: \ Users \ Pedro_Dusso \ documents \ visual studio 2010 \ Projects \ MetaManager \ MetaManager.Data \ SessionProvider.cs:line 27 at MetaManager.Data.AttributeDataService.get_Session()in C:\ Users \ Pedro_Dusso \ documents \ visual studi o 2010 \ Projects \ MetaManager \ MetaManager.Data \ Services \ AttributeDataService.cs:line 33 at MetaManager.Data.AttributeDataService.Save(Attribute attribute)in C:\ Users \ Pedro_Dusso \ documents \ visual studio 2010 \ Projects \ MetaManager \ MetaManager.Data \ Services \ AttributeDataService.cs:第58行 位於C:\ Users \ Pedro_Dusso \ documents \ visual studio 2010 \ Projects \ MetaManager \ Debug \ Program.cs中的Debug.Program.Main(String [] args):line 24 在System.AppDomain._nExecuteAssembly(RuntimeAssembly組件,字串[] args) 在System.AppDomain.ExecuteAssembly(字符串assemblyFile,證據assemblySecurity,字串[] args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在System.Threading.ThreadingHelper.ThreadStart_Context(對象狀態) at System.Threading.ExecutionContext.Run ExecutionContext executionContext,ContextCallback回調,對象狀態,Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state) at System.Threading.ThreadHelper。的ThreadStart()}再次

謝謝,

+0

什麼是您當前的ID生成器方法?甲骨文緊急,或.... _? – rebelliard 2010-10-06 12:01:26

+1

您可以使用一個oracle序列在所有表中填充id - 這將保證id在所有六個表中都是唯一的。 – andr 2010-10-06 12:50:15

回答

1

RAW是二進制類型Oracle中,它映射非常好爲唯一標識符(16個字節== 128位)

所以,定義Id屬性如Guid並使用guid.comb作爲生成器。

+0

我會盡力的! – 2010-10-06 18:35:46

+0

最後(經過一番努力正確配置..)我得到了NHibernate的工作。但是我得到這個異常:「無法將參數值從Guid轉換爲Byte []」。不應該GUID和byte []一起工作嗎?再次感謝! – 2010-10-15 18:35:15

+0

你正在做一些奇怪的類型。你能發佈你的映射嗎?你不應該有任何參考字節[] – 2010-10-16 00:08:17