1

我在 Oracle 11g 中有一个包含 6 个表的数据库(我无法修改)。所有的表都有一个 OID 人工列作为 ID,它的类型是 RAW(16)。DBA 回答我说它们是原始的而不是整数,因为这样 ID 在所有六个表中都是唯一的——我们必须保证这一点。

我正在用 C# 开发 UI,而对于数据层,我正在(尝试)使用 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.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Data.OracleClient.OracleParameter.CoerceValue(Object value, MetaType destinationType) --- 内部异常堆栈跟踪结束 --- 在 System.Data。 OracleClient.OracleParameter.CoerceValue(Object value, MetaType destinationType) 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 行为, Boolean needRowid,

老实说,我不明白你的第一个可疑之处。在数据库中,我有一个 JOB 表和一个 ETL_PROCESS 表。他们的关系就像1:n,一个JOB可以有很多个etl进程。

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

<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.ReflectionBasedDriver..ctor(String driverAssemblyName, String connectionTypeName, String commandTypeName) 在 NHibernate.Driver.OracleDataClientDriver..2 settings) --- End of inner exception stack trace --- at NHibernate.Connection.ConnectionProvider.ConfigureDriver(IDictionary2 设置)在 NHibernate.Connection.ConnectionProvider.Configure(IDictionary2 settings) at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(IDictionary2 设置)在 NHibernate.Cfg.Configuration.BuildSettings() 在 NHibernate.Cfg.Configuration.BuildSessionFactory() 在 MetaManager.Data.SessionProvider.get_Session() 在 C 中的 NHibernate.Cfg.SettingsFactory.BuildSettings(IDictionary`2 属性): \Users\Pedro_Dusso\documents\visual studio 2010\Projects\MetaManager\MetaManager.Data\SessionProvider.cs:第 27 行 MetaManager.Data.AttributeDataService.get_Session() 在 C:\Users\Pedro_Dusso\documents\visual studio 2010\Projects \MetaManager\MetaManager.Data\Services\AttributeDataService.cs:C:\Users\Pedro_Dusso\documents\visual studio 2010\Projects\MetaManager\MetaManager.Data\Services 中 MetaManager.Data.AttributeDataService.Save(属性属性)的第 33 行\AttributeDataService.cs:C 中 Debug.Program.Main(String[] args) 的第 58 行:\Users\Pedro_Dusso\documents\visual studio 2010\Projects\MetaManager\Debug\Program.cs:System.AppDomain._nExecuteAssembly 的第 24 行(RuntimeAssembly 程序集,String[] args)在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity , String[] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx ) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart()}String[] args) 在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System。 Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()}String[] args) 在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System。 Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()}Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()}Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()}

再次感谢,

4

1 回答 1

1

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

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

于 2010-10-06T12:59:26.217 回答