gpt4 book ai didi

c# - 我可以在 NHibernate 中重新附加集合吗?

转载 作者:太空宇宙 更新时间:2023-11-03 11:17:41 26 4
gpt4 key购买 nike

我有一些对象,其中一些对象有文档列表,其他对象,......等等。我不想在关系上使用 lazy=false,因为它会使应用程序非常慢。我可以使用 Lock 重新附加对象,因此其他属性或一对多关系会在它们应该加载的时候加载。但是对于集合,如果我尝试访问它们,我总是得到“无法初始化集合”。如果我在连接到该位置的对象上调用 Lock(obj),它将不起作用。

我希望我的映射看起来像这样:

<set name="DocumentList" table="material_document" cascade="all" lazy="true">
<key column="material_id"/>
<many-to-many class="Document">
<column name="document_id"/>
</many-to-many>
</set>

有没有重新连接的方法?还是有映射设置?

更新1:

这是物质方面的映射:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
<class name="Material" table="material">
<!-- Defining PK -->
<id name="Id" type="integer" column="id">
<generator class="sequence">
<param name="sequence">material_id_seq</param>
</generator>
</id>
<!-- Defining Properties -->
<!-- Defining FK-Relations -->
<set name="DocumentList" table="material_document" cascade="all" lazy="false">
<key column="material_id"/>
<many-to-many class="Document">
<column name="document_id"/>
</many-to-many>
</set>

文档映射文件没有任何关于关系的信息。数据库名称没问题,其他一切正常。这些表称为 materialmaterial_documentdocument。我的类是 public 和属性 public virtual。我的实体有什么问题?您是说数据有问题还是程序中的对象可能发生了问题...?

List material = LoadAllMaterials();
//some code, that causes the session to be closed, a new session will be opened
foreach (Document d in material.DocumentList) { //causes the exception
//do something
}

在此之前,我想获取文档,而不是事先加载它们。

更新 2:我目前如何重新附加对象:当我知道有一个代理并且它不能以其他方式工作时,我将 force 设置为 true ...我必须检查它是否在 session 中,因为如果我在不在 session 中的对象上调用它,evict 会抛出异常.

public void Reattach(Type type, BaseObject o, bool force)
{
bool inSession = o.IsInSession();

if (force && inSession)
{
GetSession().Evict(o);
GetSession().Lock(type.ToString(), o, LockMode.None);
}
else {

o = (BaseObject)GetSession().GetSessionImplementation().PersistenceContext.Unproxy(o);

if (!inSession) {

GetSession().Lock(type.ToString(), o, LockMode.None);
}
}
}

这是我的 IsInSession() 方法:

public virtual bool IsInSession() {

ISession session = HibernateSessionManager.Instance.GetSession();

var pers = session.GetSessionImplementation()
.GetEntityPersister(GetType().ToString(), this);

NHibernate.Engine.EntityKey key = new NHibernate.Engine.EntityKey(Id,
pers, EntityMode.Poco);

bool isInSession = false;

try
{
object entity = session.GetSessionImplementation().PersistenceContext.GetEntity(key);

if (entity != null)
{
isInSession = true;
}
}
catch (NonUniqueObjectException) {}

return isInSession;
}

最佳答案

我确实看到您的一个映射中有 lazy="false"...NHibernate 默认使用延迟加载,因此我将从您的映射中删除所有 lazy="false"和 lazy="true"语句并使用 NHibernate 默认设置。

我创建了以下 NUnit 测试,并且两个测试都通过了,所以我无法复制您的问题,这意味着它要么是您的 lazy="false"映射问题,要么是其他问题……如果没有,总是很难诊断这些问题将完整的应用程序呈现在您面前...

使用以下测试用例,我能够创建以下错误:“初始化 [SampleApplication.Customer#19] - 未能延迟初始化角色集合:SampleApplication.Customer.Addresses,没有 session 或 session 已关闭”

[Test]
public void Testing_A_Detached_Entity()
{
// Arrange
var sessionFactory = ObjectFactory.GetInstance<ISessionFactory>();

Customer customer = null;

using ( ISession session = sessionFactory.OpenSession() )
{
using ( ITransaction tx = session.BeginTransaction() )
{
customer = session.Query<Customer>()
.Where( x => x.CustomerNbr == 19 )
.FirstOrDefault();
}
}

// Act
TestDelegate actionToPerform = () =>
{
// Looping over this child collection should throw an Exception
// because we no longer have an active NHibernate session
foreach ( var address in customer.Addresses )
{

}
};

// Assert
Assert.Throws<NHibernate.LazyInitializationException>( actionToPerform );
}

使用以下测试用例并使用 NHibernate 的 session.Lock() 方法,我能够成功地重新附加分离的对象并获得我的子集合的计数。

[Test]
public void Testing_Reattaching_A_Detached_Entity()
{
// Arrange
var sessionFactory = ObjectFactory.GetInstance<ISessionFactory>();

Customer customer = null;

using ( ISession session = sessionFactory.OpenSession() )
{
using ( ITransaction tx = session.BeginTransaction() )
{
customer = session.Query<Customer>()
.Where( x => x.CustomerNbr == 19 )
.FirstOrDefault();
}
}

// Act
ISession newSession = sessionFactory.OpenSession();

newSession.Lock( customer, LockMode.None );

// Assert
Assert.That( customer.Addresses.Count > 0 );
}

关于c# - 我可以在 NHibernate 中重新附加集合吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12155992/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com