Should I use Hilo or Guid? + How do i use Hilo
I been reading nhibernate 3 for beginners and saw that I should not be using auto id's through MS Sql 2008 as this breaks the unit of work(what I am looking at implementing).
In the book they seem to recommend Hilo but I still don't really get them and how they keep everything unique. From what I read it makes like huge gaps in the id's and that you may need bigger data types to keep it from using all the combinations(I am currently using int).
So the other recommendation I see is GUID what would not have this problem but are a bit harder to read(if you got to compare something manually in the db) and take a bit more room up.
So right now I am just trying to make a sample project and see how hilo works.
I got a simple table with 2 fields(one pk and one some varchar)
public class HiLo
{
public virtual int Id { get; set; // not sure if this should be a private set. I see it both ways }
public virtual string Title { get; set; }
}
public class HiLoMapping : ClassMap<HiLo>
{
public HiLoMapping()
{
Id(x => x.Id).GeneratedBy.HiLo("100");
Map(x => x.Title);
}
}
not sure what 开发者_如何学运维100 actually means but it does not work.
NHibernate.Exceptions.GenericADOException was caught
Message=could not get or update next value[SQL: ]
Source=NHibernate
StackTrace:
at NHibernate.Engine.TransactionHelper.Work.DoWork(IDbConnection connection, IDbTransaction transaction)
at NHibernate.Transaction.AdoNetTransactionFactory.ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork work, Boolean transacted)
at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork work, Boolean transacted)
at NHibernate.Engine.Transaction.Isolater.DoIsolatedWork(IIsolatedWork work, ISessionImplementor session)
at NHibernate.Engine.TransactionHelper.DoWorkInNewTransaction(ISessionImplementor session)
at NHibernate.Id.TableGenerator.Generate(ISessionImplementor session, Object obj)
at NHibernate.Id.TableHiLoGenerator.Generate(ISessionImplementor session, Object obj)
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at unitofwork.Models.Repository.StoreRepo.Create(HiLo hilo) in ]StoreRepo.cs:line 32
at unitofwork.Models.Service.StoreService.CreateStore() inStoreService.cs:line 33
InnerException: System.Data.SqlClient.SqlException
Message=Invalid object name 'hibernate_unique_key'.
Source=.Net SqlClient Data Provider
ErrorCode=-2146232060
Class=16
LineNumber=1
Number=208
Procedure=""
Server=(local)
State=1
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at NHibernate.Id.TableGenerator.DoWorkInCurrentTransaction(ISessionImplementor session, IDbConnection conn, IDbTransaction transaction)
at NHibernate.Engine.TransactionHelper.Work.DoWork(IDbConnection connection, IDbTransaction transaction)
InnerException:
Right now in my db I have 3 tables(2 with auto id and one with hilo). The hilo table is sort of floating around byitself where the other 2 tables have a relationship.
For an explanation of HiLo, the simplest, most concise one I've ever read is What's the Hi/Lo algorithm?.
As for your example not working, you're missing the hibernate_unique_key table (which is the default named Hilo table).
The simplest way to fix it, is to get NHibernate to create it for you - set the SchemaAutoAction property on the Nhibernate configuration to 'Update'.
You need to create the HiLo table, check it here
I usually work with Guid.Comb, since its easier to me since I usually share the same database with another systems that doesn't know about HiLo
精彩评论