开发者

What are the different GeneratedBy's in nhibernate/fluent nhibernate

开发者 https://www.devze.com 2023-04-05 09:11 出处:网络
I am playing around with nhibernate and fluent nhibernate and looking at GeneratedBy and there so many to choose(sequence,sequenceIdentity,etc) from but I don\'t know what most of them do.

I am playing around with nhibernate and fluent nhibernate and looking at GeneratedBy and there so many to choose(sequence,sequenceIdentity,etc) from but I don't know what most of them do.

I see for instance 3 Guid ones.

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

I heard not to use Guid() and use GuidComb as it is specially designed for working with databases(it does not break indexes).

I don't know what GuidNative() is though.

I also was trying to make

GeneratedBy.Native()

I thought that would use whatever MSSQl 2008 uses but I am running into problem with it

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]

I thought by doing

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

a Id would automatically be generated for me by nhibernate(it does this if I use combGuid()) but when I try to commit it I 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.R开发者_JAVA技巧epository.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: 

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?

I am just playing with the ids as I was shocked to learn that the way I was doing it was not a good way(I set in my database as an auto incrementing int which is what I always did for like ado.net and linq to sql).

By doing this everytime a save happened an extra query to the db would happen(to get the pk). So I am playing around to see what combinations cause this to happen.

I am starting to lean more to using Guid(even though I rather have something a bit shorter so it is faster to match up in other tables if you got to look manually at the db for some reason).

I was thinking of hilo but the thing I don't like about that is if I ever got to switch out ORM's to say the Entity Framework the hilo might not be supported. Plus what I heard about using HiLO that it can go through tons of id's very quickly making you need bigger datatypes.


see NHibernate Docs for the various generators. IMO GUID(Comb) or HiLo have the best performance because Ids can be generated in the application. If you use HiLo you can easily switch to an ORM without that feature, just create a sequence with value > max(Id) and use that as default value for the column to simulate autoincrementing.

Note: In my projects i always used HiLo with success so I am biased.


MSSQL native uses auto identity. You need to turn auto identity on ID column for NHibernate to insert.

Check out this other article about not using identity generator: http://ayende.com/blog/3915/nhibernate-avoid-identity-generator-when-possible


"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?"

This will not work when you have two instances of the app hitting the database.

With integer Id's, you pretty much have to have the db providing some sort of synchronization.

If you choose Identity, you have to immediately call scope_identity() after the insert if you need the Id. And since NHibernate always needs the Id for entities that you session.Save(), it is going to do exactly that.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号