我有一个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()}再次
谢谢,
什么是您当前的ID生成器方法?甲骨文紧急,或.... _? – rebelliard 2010-10-06 12:01:26
您可以使用一个oracle序列在所有表中填充id - 这将保证id在所有六个表中都是唯一的。 – andr 2010-10-06 12:50:15