如何使用NHibernate插入或更新(或覆盖)记录? [英] How do I Insert or Update (or overwrite) a record using NHibernate?

查看:77
本文介绍了如何使用NHibernate插入或更新(或覆盖)记录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要向数据库写一行,无论它是否已经存在.在使用NHibernate之前,这是通过存储过程完成的.该过程将尝试更新,如果未修改任何行,则将回退到插入.之所以能奏效,是因为该应用程序不在乎记录是否存在.

I need to write a row to the database regardless of whether it already exists or not. Before using NHibernate this was done with a stored procedure. The procedure would attempt an update and if no rows were modified it would fallback to an insert. This worked well because the application doesn't care if the record exists.

使用NHibernate,我发现的解决方案要求加载实体并对其进行修改,或者删除该实体,以便可以插入新实体.应用程序必须注意记录是否已经存在.有办法解决吗?

With NHibernate, the solutions I have found require loading the entity and modifying it, or deleting the entity so the new one can be inserted. The application does have to care if the record already exists. Is there a way around that?

该对象具有一个关键字作为分配的ID,并且是表中的主键.

The object has a keyword as an assigned id and is the primary key in the table.

我知道SaveOrUpdate()将根据ID适当地调用Save()或Update()方法.使用分配的ID,这将无效,因为该ID并非未保存的值.但是,可以将版本"或时间戳记"字段用作指示符.实际上,这无关紧要,因为这仅反映内存中的对象是否已与数据库中的记录相关联.它不会指示该记录是否存在于数据库中.

I understand that SaveOrUpdate() will call the Save() or Update() method as appropriate based on the Id. Using an assigned id, this won't work because the id isn't an unsaved-value. However a Version or Timestamp field could be used as an indicator instead. In reality, this isn't relevant because this only reflects on whether the object in memory has been associated with a record in the database; it does not indicate if the record exists or not in the database.

如果分配的ID确实是问题的原因,则可以使用生成的ID代替关键字作为主键.这将避免NHibernate插入/更新问题,因为它将始终有效地插入.但是,我仍然需要防止重复的关键字.在关键字列上具有唯一索引的情况下,即使主键不同,它仍然会为重复的关键字引发异常.

If the assigned id were truly the cause of the problem, I could use a generated id instead of the keyword as the primary key. This would avoid the NHibernate Insert/Update issue as it would effectively always insert. However, I still need to prevent duplicate keywords. With a unique index on the keyword column it will still throw an exception for a duplicate keyword even if the primary key is different.

也许问题不是NHibernate真正的问题,而是问题的建模方式.与应用程序的其他领域不同,这是更以数据为中心而不是以对象为中心的. NHibernate使其易于读取/写入并消除了存储过程,这是一个很好的选择.但是,简单地写而不考虑现有值的愿望与对象的身份模型的模型不太吻合.有没有更好的方法来解决这个问题?

Perhaps the problem isn't really with NHibernate, but the way this is modeled. Unlike other areas of the application, this is more data-centric rather object-centric. It is nice that NHibernate makes it easy to read/write and eliminates the stored procedures. But the desire to simply write without regard to existing values doesn't fit well with the model of an object's identity model. Is there a better way to approach this?

推荐答案

我使用

    public IList<T> GetByExample<T>(T exampleInstance)
    {
        return _session.CreateCriteria(typeof(T))
                    .Add(Example.Create(exampleInstance))
                    .List<T>();
    }

    public void InsertOrUpdate<T>(T target)
    {
        ITransaction transaction = _session.BeginTransaction();
        try
        {
            var res=GetByExample<T>(target);
            if( res!=null && res.Count>0 )
                _session.SaveOrUpdate(target);
            else
               _session.Save(target); 
            transaction.Commit();
        }
        catch (Exception)
        {
            transaction.Rollback();
            throw;
        }
        finally
        {
            transaction.Dispose();
        }
    }

但是FindByExample方法返回所有类似的对象,而不返回具有确切ID的对象,这是什么建议?因为我只有对象作为参数,所以我无权访问其特定的ID字段,因此无法使用session.get(Object.class(), id);

but FindByExample method returns all objects alike not objects with the exact ID what do you suggest ? since I have only object as parameter I don't have access to its specific ID field so I cannot use session.get(Object.class(), id);

这篇关于如何使用NHibernate插入或更新(或覆盖)记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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