Должен ли я использовать Hilo или Guid?+ Как я могу использовать Hilo - PullRequest
2 голосов
/ 13 сентября 2011

Я читал nhibernate 3 для начинающих и понял, что не должен использовать автоматические идентификаторы в MS Sql 2008, так как это нарушает единицу работы (что я смотрю на реализацию).

В книге они, кажется, рекомендуют Хило, но я до сих пор не понимаю их, и как они сохраняют все уникальным. Из того, что я прочитал, это делает огромные пробелы в идентификаторах, и что вам могут потребоваться большие типы данных, чтобы не использовать все комбинации (в настоящее время я использую int).

Итак, другая рекомендация, которую я вижу, это GUID, которая не будет иметь этой проблемы, но ее немного сложнее читать (если вам нужно сравнить что-то вручную в БД) и занять немного больше места.

Так что сейчас я просто пытаюсь сделать пример проекта и посмотреть, как работает hilo.

Я получил простую таблицу с 2 полями (один ПК и один несколько 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);
    }
}

не уверен, что на самом деле означает 100, но это не работает.

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: 

Прямо сейчас в моей базе данных у меня есть 3 таблицы (2 с автоматическим идентификатором и одна с hilo). Стол hilo как бы плавает вокруг себя, где у двух других таблиц есть связь.

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Вам необходимо создать таблицу HiLo, проверить ее здесь

Я обычно работаю с Guid.Comb, так как мне проще, поскольку я обычно делю одну и ту же базу данных с другими системами, которыене знает о HiLo

1 голос
/ 14 сентября 2011

Для объяснения HiLo самым простым и кратким из всех, что я когда-либо читал, является Что такое алгоритм Hi / Lo? .

Поскольку ваш пример не работает, вам не хватает таблицы hibernate_unique_key (которая по умолчанию называется Hilo table).

Самый простой способ исправить это - заставить NHibernate создать его для вас - установите для свойства SchemaAutoAction в конфигурации Nhibernate значение «Обновить».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...