2010-10-06 82 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