在NHibernate和Oracle中实现hilo(或seqhilo)

我有一个数据库(我无法修改)在Oracle 11g中有6个表。 所有表都有一个用于ID的OID人工列,其类型为RAW(16)。 数据库管理员回答我说他们是原始数据,而不是整数,因为这样ID在所有六张表中都是唯一的 - 我们必须保证这一点。

我正在开发用户界面在C#和数据层我(尝试)使用NHibernate。 我怎样才能以这种必需品的方式实现ID生成器?

非常感谢,

佩德罗·杜索

我的地图是:

<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 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.Data.OracleClient.OracleParameter.CoerceValue(Object value,MetaType destinationType)处的System.Convert.ChangeType(Object value,Type conversionType,IFormatProvider provider) - 内部异常堆栈跟踪结束---在System.Data。 System.Data.OracleClient.OracleParameterBinding.PrepareForBind(OracleConnection连接,Int32&offset)上System.Data.OracleClient.OracleParameter.SetCoercedValueInternal(Object value,MetaType metaType)上的OracleClient.OracleParameter.CoerceValue(Object value,MetaType destinationType) .OracleClient.OracleCommand.Execute(OciStatementHandle statementHandle,CommandBehavior行为,布尔needRowid,OciRowidDescriptor&rowidDescriptor,ArrayList&resultParameterOrdinals)在System.Data.OracleClient.OracleCommand.ExecuteNonQueryInternal(布尔needRowid,OciRowidDescriptor&rowidDescriptor)在System.Data.OracleClient.OracleCommand.ExecuteNonQuery( )在NHibernate的NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd) 在NHibernate中,NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id,Object [] fields,Boolean [] notNull,Int32 j,SqlCommandInfo sql,Object obj,ISessionImplementor session)提供了nate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)。 Persistence.Entity.AbstractEntityPersister.Insert(Object id,Object [] fields,Object obj,ISessionImplementor session)NHibernate.Action.EntityInsertAction.Execute()NHibernate.Engine.ActionQueue.Execute(IExecutable executable)at NHibernate.Engine.ActionQueue 。NHibernate.Engine.ActionQueue.ExecuteActions()上的.ExecuteActions(IList列表)在NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource会话)在NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent事件)在​​NHibernate.Impl.SessionImpl .Flush()at NHManager.Transaction.AdoTransaction.Commit()at MetaManager.Data.Services.JobDataControl.Save(Job job)in C: Users Pedro_Dusso documents visual studio 2010 Projects MetaManage r MetaManager.Data Services JobDataControl.cs:第45行}

真诚的,我不明白你的第一个可疑。 在数据库中,我有一个JOB表和一个ETL_PROCESS表。 他们的关系像1:n,一个JOB可以有很多etl过程。

PS:我正在添加我的nhibernate配置,也许它有帮助。

<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>

使用ODP时出错:{NHibernate.HibernateException:无法从NHibernate.Driver.OracleDataClientDriver创建驱动程序。 ---> System.Reflection.TargetInvocationException:调用的目标引发了异常。 ---> NHibernate.HibernateException:无法找到程序集Oracle.DataAccess中的IDbCommand和IDbConnection实现。 确保程序集Oracle.DataAccess位于应用程序目录或全局程序集缓存中。 如果程序集位于GAC中,请使用应用程序配置文件中的元素指定程序集的全名。 在NHibernate.Driver.OracleDataClientDriver..ctor()---内部异常堆栈跟踪结束---在System.RuntimeTypeHandle.CreateInstance(RuntimeType)上的NHibernate.Driver.ReflectionBasedDriver..ctor(String driverAssemblyName,String connectionTypeName,String commandTypeName) (布尔publicOnly,布尔skipCheckThis,布尔fillCache)在布尔publicOnly,布尔skipVisibilityChecks,布尔skipCheckThis布尔publicOnly,布尔skipCheckThis,布尔fillCache)布尔skipCheckThis,布尔skipCheckThis,布尔noCheck,布尔和canBeCached,RuntimeMethodHandleInternal&ctor,布尔和bNeedSecurityCheck)在System.Activator.CreateInstance(类型类型,布尔nonPublic)在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.Conn 2 settings) at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(IDictionary )上NHibernate.Cfg.SettingsFactory.BuildSettings(IDictionary`2属性)NHibernate.Cfg 2 settings) at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(IDictionary 2设置)配置2 settings) at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(IDictionary 2设置)。 C: Users Pedro_Dusso documents visual studio 2010 Projects MetaManager MetaManager.Data SessionProvider.cs中的MetaManager.Data.SessionProvider.get_Session()中的Configuration.BuildSessionFactory():MetaManager.Data.AttributeDataService中的第27行。 C: Users Pedro_Dusso documents visual studio 2010 Projects MetaManager MetaManager.Data Services AttributeDataService.cs中的get_Session():C: Users中MetaManager.Data.AttributeDataService.Save(属性属性)的第33行 Pedro_Dusso documents visual studio 2010 Projects MetaManager MetaManager.Data Services AttributeDataService.cs:C: Users Pedro_Dusso documents visual studio 2010中Debug.Program.Main(String [] args)的第58行项目 MetaManager 调试程序 .cs:System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String [] args)上的System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args) System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state)在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object state,Boolean ignoreSyncCtx)上System.Threading.ThreadHelper.ThreadStart_Context(Object state) )在System.Threading.ThreadHelper.ThreadStart()}

再次感谢,


RAW是Oracle中的一种二进制类型,它很好地映射到唯一标识符(16字节== 128位)

因此,将您的Id属性定义为Guid并使用guid.comb作为生成器。

链接地址: http://www.djcxy.com/p/19115.html

上一篇: Implementing hilo (or seqhilo) in NHibernate and Oracle

下一篇: Explanation of NHibernate HiLo