从与NHibernate的HasMany关系中读取未提交的数据 [英] Read uncomitted data from HasMany-relationship with NHibernate

查看:96
本文介绍了从与NHibernate的HasMany关系中读取未提交的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个NHibernate映射,该映射定义了一个类型的HasMany关系,即一个类具有另一个类的列表.

I have an NHibernate map which defines a HasMany-relationship on a type, i.e. a class has a list of another class.

我希望NHibernate能够读取未提交的数据,包括由HasMany关系生成的列表.

I would like NHibernate to be able to read uncommitted data including the list resulting from the HasMany-relationship.

我具有隔离级别ReadUncomitted,并且能够在提交之前写数据并将其读回.

I have isolationlevel ReadUncomitted and I am able to write data and read it back before committing.

但是,除非我先提交,否则列表始终为空.

However, the list is always empty, unless I commit first.

是否有一种方法可以使NHibernate使用HasMany关系中的数据填充对象?

Is there a way to make NHibernate populate objects with data from HasMany-relationships?

编辑

事实证明,除非确实将类中的所有非基本类型实际添加到该类中,否则它们都不会被未提交的读取填充.

It turns out any non-primitive types on a class are not populated by an uncommitted read unless they are actually added to the class.

例如,下面的类Foo具有Member的列表,该列表-在数据库中-通过Id连接.如果我使用NHibernate将Foo的实例和Member的实例持久化到数据库,并且实际上两者都与Id的值相关,则Foo not 包含Member的预期实例,如果我未提交(即在完成交易之前)将其读回.

For example, class Foo below has a list of Member which - in the database - are connected by Id. If I persist an instance of Foo and an instance of Member to the database using NHibernate and both are in fact related by the value of Id, then Foo will not have the expected instance of Member if I read it back uncommitted (i.e. before completing the transaction).

public class Member
{
     Guid Id{ get; set; }
}

public class Foo
{
    List<Member> MemberList{ get; set; }
}

// the mapping
public class FooMap
{
    HasMany(x => x.MemberList).KeyColumn("Id").PropertyRef("Id");
}

但是,如果我创建一个Foo的实例和一个Member的实例,并将后者设置为前者的引用,并使用NHibermate将其持久化到数据库,则Foo 具有预期的Member实例.

However, If I create an instance of Foo and an instance of Member and set the latter as a reference of the former and persist both to the database using NHibermate, then Foo will have the expected instance of Member when I read it back before completing the transaction.

如果我完成交易,则Foo在后续读取时将具有Member的预期实例;只要事务完成,Member仅作为具有正确的FK到Foo的数据库记录存在还是作为对Foo的引用都无关紧要.

If I complete the transaction then Foo will have the expected instance of Member on subsequent reads; as long as the transaction is completed it is irrelevant whether Member existed only as a database record with the correct FK to Foo or it was a reference to Foo.

修订后的问题: 在未提交的读取期间,NHibernate是否有可能仅基于 FK关系填充复杂成员?

Revised Question: It is possible have NHibernate populate complex members based on FK-relationships only during an uncommitted read?

推荐答案

这里似乎存在一些一般性的混淆,因此需要澄清一些事情:

There seems to be some general confusion here, so to clarify a few things:

  • 事务的隔离级别仅影响 other 的更改 交易可见.事务始终可以回读已修改的数据.

  • The isolation level of a transaction only affects what changes from other transactions are visible. A transaction can always read back data it has modified itself.

如果遵循该命令,则对事务的Commit()调用与是否 拥有事务的NHibernate会话是否可以读回那些更改 或不.永远可以.

If follows that the call to Commit() for the transaction has nothing to with whether or not the NHibernate session that owns the transaction can read back those changes or not. It always can.

但是,NHibernate不会修改已经加载的实例.您,作为开发人员 的模型,负责更改已加载的实体,确保模型 仍然有效并且与您的业务规则一致,然后NHibernate将 将更改存储在数据库中.成为您模型的一部分不是NHibernate的工作 与您在另一部分所做的更改保持一致.

However, NHibernate will not modify an already loaded instance. You, as the developer of the model, is responsible for making changes in loaded entities, making sure the model is still valid and consistent with your business rules, and then NHibernate will store the changes in the DB. It is not NHibernate's job to make a part of you model consistent with changes you made in another part.

作为NHibernate,在调用Commit()之前或之后进行读均无所谓 保证一个会话最多只包含每个实体的一个副本.所以什么时候 您查询刚刚保存的对象,您将获得与原来相同的信息 已加载的未修改实例.

Reading back before or after the call to Commit() doesn't matter, as NHibernate guarantees that a session will only contain at most one copy of each entity. So when you query for the object you just saved, you will just get back the same, already loaded, unmodified instance.

重要的是,如果您关闭会话并为查询打开一个新会话.然后 NHibernate将再次实例化该对象,它将反映当前状态 数据库.如果您使用原始会话,可以达到相同的效果 会话上的Clear()或Evict()(在调用Flush()或Commit()之后).这些 方法从会话中删除已经加载的实例,因此下次您 查询它,会话将创建一个新实例,该实例然后将反映从当前事务可见的数据库当前状态.

What matters is if you close the session and open a new session for your query. Then NHibernate will instantiate the object again, and it will reflect the current state of the database. The same effect can be had in the original session if you use Clear() or Evict() on the session (after having called Flush() or Commit()). These methods remove the already loaded instance from the session, so the next time you query for it, the session will create a new instance, which would then of course reflect the current state of the database, as visible from the current transaction.

这篇关于从与NHibernate的HasMany关系中读取未提交的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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