Каковы различные GeneratedBy в nhibernate / свободный nhibernate - PullRequest
3 голосов
/ 14 сентября 2011

Я играю с nhibernate и беглым nhibernate и смотрю на GeneratedBy, и там есть из чего выбирать (sequence, sequenceIdentity и т. Д.), Но я не знаю, что делает большинство из них.

Я вижунапример, 3 Guid.

GeneratedBy.Guid();
GeneratedBy.GuidComb();
GeneratedBy.GuidNative();

Я слышал, что не следует использовать Guid () и использовать GuidComb, так как он специально разработан для работы с базами данных (он не нарушает индексы).

Iне знаю, что такое GuidNative().

Я также пытался сделать

GeneratedBy.Native()

Я думал, что будет использовать то, что использует MSSQl 2008, но у меня возникли проблемы с ним

CREATE TABLE [dbo].[AutoIds](
    [Id] [int] NOT NULL,
    [Test] [varchar](50) NULL,
 CONSTRAINT [PK_AutoIds] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Я подумал, что при

  Id(x => x.Id).GeneratedBy.Native();

Ih автоматически генерирует Id (он делает это, если я использую combGuid ()), но когда я пытаюсь его зафиксировать, яget

NHibernate.Exceptions.GenericADOException was caught
  Message=could not insert: [unitofwork.Models.Domain.AutoIds][SQL: INSERT INTO [AutoIds] (Test) VALUES (?); select SCOPE_IDENTITY()]
  Source=NHibernate
  SqlString=INSERT INTO [AutoIds] (Test) VALUES (?); select SCOPE_IDENTITY()
  StackTrace:
       at NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)
       at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
       at NHibernate.Action.EntityIdentityInsertAction.Execute()
       at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
       at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
       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(AutoIds autoIds) in StoreRepo.cs:line 37
       at unitofwork.Models.Service.StoreService.CreateStore() inStoreService.cs:line 40
  InnerException: System.Data.SqlClient.SqlException
       Message=Cannot insert the value NULL into column 'Id', table 'TESTUoW.dbo.AutoIds'; column does not allow nulls. INSERT fails.
The statement has been terminated.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=16
       LineNumber=1
       Number=515
       Procedure=""
       Server=(local)
       State=2
       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.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
            at NHibernate.Id.IdentityGenerator.InsertSelectDelegate.ExecuteAndExtract(IDbCommand insert, ISessionImplementor session)
            at NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       InnerException: 

Может ли nhibernate не делать автоматическое увеличение целых чисел?Это слишком сложно, чтобы отследить следующий номер?

Я просто играю с идентификаторами, так как я был шокирован, узнав, что то, как я это делал, было нехорошо (я установил в своей базе данных значение int с автоматическим приращением, что я всегда делал какado.net и linq to sql).

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

Я начинаю больше склоняться к использованию Guid (даже если у меня есть что-то немного короче, так что быстрее сопоставляться в других таблицах, еслипо какой-то причине вы должны посмотреть на базу данных вручную.

Я думал о hilo, но мне не нравится в этом то, что мне когда-либо приходится переключать ORM, чтобы сказать Entity Framework как hiloможет не поддерживатьсяПлюс к тому, что я слышал об использовании HiLO, он может очень быстро проходить через тонны идентификаторов, заставляя вас нуждаться в больших типах данных.

Ответы [ 3 ]

2 голосов
/ 15 сентября 2011

см. Документы NHibernate для различных генераторов. IMO GUID (Comb) или HiLo имеют лучшую производительность, потому что идентификаторы могут быть сгенерированы в приложении. Если вы используете HiLo, вы можете легко переключиться на ORM без этой функции, просто создайте последовательность с value > max(Id) и используйте ее в качестве значения по умолчанию для столбца для имитации автоинкремента.

Примечание: в своих проектах я всегда с успехом использовал HiLo, поэтому я предвзят.

1 голос
/ 11 января 2012

MSSQL native использует автоматическую идентификацию. Вам нужно включить автоматическую идентификацию в столбце ID для NHibernate для вставки.

Ознакомьтесь с этой статьёй о том, как не использовать генератор идентификаторов: http://ayende.com/blog/3915/nhibernate-avoid-identity-generator-when-possible

0 голосов
/ 15 сентября 2011
"Can nhibernate not do auto incrementing ints?  Is that just something too hard to keep track of for it to figure out the next number?"

Это не будет работать, если у вас есть два экземпляра приложения, попадающего в базу данных.

При использовании целочисленных идентификаторов вам, скорее всего, потребуется база данных, обеспечивающая некоторую синхронизацию.

Если вы выбираете Identity, вам нужно немедленно вызвать scope_identity () после вставки, если вам нужен Id. А поскольку NHibernate всегда нуждается в Id для сущностей, с которыми вы выполняете сеанс. Save (), он будет делать именно это.

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