NHibernate HiLo ID生成器.保存前生成ID [英] NHibernate HiLo ID Generator. Generating an ID before saving

查看:79
本文介绍了NHibernate HiLo ID生成器.保存前生成ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在NHibernate中使用'adonet.batch_size'属性.现在,我将在多个会话中创建实体(因此批量插入).因此,我要做的是创建一个缓冲区,在其中保留这些实体,它们会定期一次将它们全部清除掉.

I'm trying to use 'adonet.batch_size' property in NHibernate. Now, I'm creating entities across multiple sessions at a large rate (hence batch inserting). So what I'm doing is creating a buffer where I keep these entities and them flush them out all at once periodically.

但是,一旦创建实体,我就需要ID.所以我想创建一个实体(在任何会话中),然后生成其ID(我正在使用HiLo生成器).然后,在以后的时间(和其他会话)中,我要刷新该缓冲区并确保这些ID不变.

However I need the ID's as soon as I create the entities. So I want to create an entity (in any session) and then have its ID generated (I'm using HiLo generator). And then at a later time (and other session) I want to flush that buffer and ensure that those IDs do not change.

反正有这样做吗?

谢谢

Guido

推荐答案

我觉得很奇怪,您需要很多会话才能完成一项工作.通常,一个会话就可以完成所有工作.

I find it odd that you need many sessions to do a single job. Normally a single session is enough to do all work.

也就是说,Hilo生成器在调用nhSession.Save(object)时在实体上设置id属性,而不必要求往返数据库和 nhSession.Flush()会将插入内容刷新到数据库

That said, the Hilo generator sets the id property on the entity when calling nhSession.Save(object) without necessarily requiring a round-trip to the database and a nhSession.Flush() will flush the inserts to the database

更新=============================================== ============================

UPDATE ===========================================================================

这是我在特定情况下使用的一种方法,该方法在保持NHibernate兼容性的同时进行了纯SQL插入.

This is a method i used on a specific case that made pure-sql inserts while maintaining NHibernate compatibility.

//this will get the value and update the hi-lo value repository in the datastore
public static void GenerateIdentifier(object target)
{
      var targetType = target.GetType();
      var classMapping = NHibernateSessionManager.Instance.Configuration.GetClassMapping(targetType);
      var impl = NHibernateSessionManager.Instance.GetSession().GetSessionImplementation();

      var newId = classMapping.Identifier.CreateIdentifierGenerator(impl.Factory.Dialect, classMapping.Table.Catalog, classMapping.Table.Schema,
                                                              classMapping.RootClazz).Generate(impl, target);
      classMapping.IdentifierProperty.GetSetter(targetType).Set(target, newId);
}

因此,此方法将像

var myEnt = new MyEnt(); //has default identifier
GenerateIdentifier(myEnt); //now has identifier injected based on nhibernate's mapping

请注意,此调用不会将实体放置在任何类型的nhibernate受管空间中.因此,您仍然必须放置一个位置来放置对象并在每个对象上进行保存.还要注意,我将此代码与纯sql插入一起使用,除非您在实体映射中指定generator="assigned"(这将需要一些自定义的hi-lo生成器),否则nhibernate可能需要使用不同的机制来持久化它.

note that this call does not place the entity in any kind of nhibernate managed space. So you still have to make a place to place your objects and make the save on each one. Also note that i used this one with pure sql inserts and unless you specify generator="assigned" (which will then require some custom hi-lo generator) in your entity mapping nhibernate may require a different mechanism to persist it.

总而言之,您想要的是为一个对象生成一个ID,该ID将在以后的某个时间保留.这会带来一些问题,例如由于回滚和提交失败而导致处理不存在的条目.另外,imo nhibernate并不是用于此特定工作的工具,除非有某些复杂的实体逻辑(在开发时)过于昂贵(无法自行实现),否则您不需要nhibernate来进行批量插入.

All in all, what you want is to generate an Id for an object that will be persisted at some time in the future. This brings up some problems such as handling non-existent entries due to rollbacks and failed commits. Additionally imo nhibernate is not the tool for this particular job, you don't need nhibernate to do your bulk insert unless there is some complex entity logic that is too costly (in dev time) to implement on your own.

还请注意,这意味着您需要临时分离的实体,但是除非在第一个会话上调用.nhSes.Save(obj)并刷新其内容,否则第二个会话才能在临时对象上调用Load时使用.数据库中将存在一个与您要实现的目标相矛盾的行.

Also note that you are implying that you need transient detached entities which however cannot be used unless you call .nhSes.Save(obj) on the first session and flush its contents so the 2nd session when it calls Load on the transient object there will be an existing row in the database which contradicts what you want to achieve.

Imo不必担心会猛冲数据库,只需自上而下优化程序即可处理该卷.当您使用ado.net甚至是isqlquery包装查询(并使用上面提供的方法)可以以4倍的性能获得相同的结果时,仅使用nhibernate进行插入似乎会适得其反.

Imo don't be afraid of storming the database, just optimise the procedure top-to-bottom to be able to handle the volume. Using nhibernate just to do an insert seems counter-productive when you can achieve the same result with 4 times the performance using ado.net or even an isqlquery wrapped-query (and use the method i provided above)

这篇关于NHibernate HiLo ID生成器.保存前生成ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆