在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
作为生成器。
上一篇: Implementing hilo (or seqhilo) in NHibernate and Oracle