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

查看:27
本文介绍了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.

有没有办法做到这一点?

Is there anyway to do this?

谢谢

圭多

推荐答案

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

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);
}

所以,这个方法需要你新建的实体,比如

So, this method takes your newly constructed entity like

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.这会带来一些问题,例如由于回滚和提交失败而处理不存在的条目.此外,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天全站免登陆