C# NHibernate,保存IDictionary:TransientObject异常

C# NHibernate,保存IDictionary:TransientObject异常,c#,nhibernate,nhibernate-mapping,instance,transient,C#,Nhibernate,Nhibernate Mapping,Instance,Transient,在我的类中,我有一个IDictionary,实体(类)作为键,角色(枚举)作为值。尝试保存Case的新实例(非持久化)时,如果IDictionary中填充了Entity的新实例,则会出现以下错误: NHibernate.TransientObject异常:对象引用未保存的临时实例-在刷新之前保存临时实例。类型:实体 这些是类(角色是枚举): 地图如下: <class name="Case" table="[Case]"> <id name="Id" column="Id

在我的类中,我有一个IDictionary,实体(类)作为键,角色(枚举)作为值。尝试保存Case的新实例(非持久化)时,如果IDictionary中填充了Entity的新实例,则会出现以下错误:

NHibernate.TransientObject异常:对象引用未保存的临时实例-在刷新之前保存临时实例。类型:实体

这些是类(角色是枚举):

地图如下:

<class name="Case" table="[Case]">
    <id name="Id" column="Id" type="Int32" unsaved-value="any">
        <generator class="hilo"/>
    </id>
    <map name="EntityCollection" table="CaseEntityRoles" 
     cascade="save-update" lazy="false" inverse="false">
        <key column="CaseId" />
        <index-many-to-many class="Entity" 
         column="EntityId" />
        <element column="Roles" type="Roles" not-null="true" />
    </map>
</class>
在测试代码中,newCase实例是持久化的,但新实体不是。我已经尝试了很多不同的事情,比如给实体添加标签和处理未保存的值,但似乎没有任何帮助。正如您从映射中看到的,我有cascade=“save update”。
有什么想法吗?

如果将“反向”设置为“真”,会发生什么

我不知道这是否能解决你的问题

您可以做的是利用Repository模式,创建一个“CaseRepository”类。 在该存储库中,您将有一个保存给定案例的Save方法。 在该save方法中,可以循环给定情况下的所有实体,并为每个实体显式调用“SaveOrUpdate”


我还想知道你为什么要用字典来解决这个问题?

如果你把inverse设置为true,会发生什么

我不知道这是否能解决你的问题

您可以做的是利用Repository模式,创建一个“CaseRepository”类。 在该存储库中,您将有一个保存给定案例的Save方法。 在该save方法中,可以循环给定情况下的所有实体,并为每个实体显式调用“SaveOrUpdate”


我还想知道您为什么要使用字典来解决这个问题?

我认为您需要先持久化案例引用的实体对象,然后再尝试持久化案例。我有一个类似的问题,我用这种方法解决了。例如,使用Rhino存储库:

[Test]
public void Can_add_new_case()
{
    var newCase = new Case();
    var entity1 = new Entity();
    var entity2 = new Entity();
    newCase.EntityCollection.Add(entity1, Roles.Role1);
    newCase.EntityCollection.Add(entity2, Roles.Role2);

    Rhino.Commons.NHRepository<Entity> entityRepository = new NHRepository<Entity>();
    Rhino.Commons.NHRepository<Case> caseRepository = new NHRepository<Case>();

    using (UnitOfWork.Start())
    {
        entityRepository.SaveOrUpdate(entity1);
        entityRepository.SaveOrUpdate(entity2);
        caseRepository.SaveOrUpdate(newCase);
    }
}
[测试]
公共无效可以添加新案例()
{
var newCase=newCase();
var entity1=新实体();
var entity2=新实体();
添加(entity1,Roles.Role1);
添加(entity2,Roles.Role2);
Rhino.Commons.NHRepository entityRepository=new NHRepository();
Rhino.Commons.NHRepository casepository=新的NHRepository();
使用(UnitOfWork.Start())
{
entityRepository.SaveOrUpdate(entity1);
entityRepository.SaveOrUpdate(entity2);
casepository.SaveOrUpdate(newCase);
}
}

我认为您需要先持久化案例引用的实体对象,然后再尝试持久化案例。我有一个类似的问题,我用这种方法解决了。例如,使用Rhino存储库:

[Test]
public void Can_add_new_case()
{
    var newCase = new Case();
    var entity1 = new Entity();
    var entity2 = new Entity();
    newCase.EntityCollection.Add(entity1, Roles.Role1);
    newCase.EntityCollection.Add(entity2, Roles.Role2);

    Rhino.Commons.NHRepository<Entity> entityRepository = new NHRepository<Entity>();
    Rhino.Commons.NHRepository<Case> caseRepository = new NHRepository<Case>();

    using (UnitOfWork.Start())
    {
        entityRepository.SaveOrUpdate(entity1);
        entityRepository.SaveOrUpdate(entity2);
        caseRepository.SaveOrUpdate(newCase);
    }
}
[测试]
公共无效可以添加新案例()
{
var newCase=newCase();
var entity1=新实体();
var entity2=新实体();
添加(entity1,Roles.Role1);
添加(entity2,Roles.Role2);
Rhino.Commons.NHRepository entityRepository=new NHRepository();
Rhino.Commons.NHRepository casepository=新的NHRepository();
使用(UnitOfWork.Start())
{
entityRepository.SaveOrUpdate(entity1);
entityRepository.SaveOrUpdate(entity2);
casepository.SaveOrUpdate(newCase);
}
}

如果我将inverse设置为true,则不会出现异常,但实体仍不会保存。实际上,我确实使用了一个带有Save方法的通用存储库类,但如果NHibernate能够为我完成这项工作(如果映射正确的话),我不想为此编写额外的代码。如果我别无选择,这可能就是我必须要做的。我使用Dictionary是因为我只想为每个案例保存同一个实体一次(这就是为什么我将它们用作键)。这个想法是,如果一个实体有多个角色,我可以只使用一个标志枚举。如果这变得有问题,我可能不得不修改我的解决方案。如果我将inverse设置为true,我不会得到任何异常,但实体仍然不会被保存。实际上,我确实使用了一个带有Save方法的通用存储库类,但如果NHibernate能够为我完成这项工作(如果映射正确的话),我不想为此编写额外的代码。如果我别无选择,这可能就是我必须要做的。我使用Dictionary是因为我只想为每个案例保存同一个实体一次(这就是为什么我将它们用作键)。这个想法是,如果一个实体有多个角色,我可以只使用一个标志枚举。如果这成为问题,我可能不得不修改我的解决方案。是的,这也是我最后所做的。遗憾的是,NHibernate并没有自动处理这个问题。如果有人知道任何其他解决方案(或者知道这个bug,如果它是bug,什么时候会被修复),请告诉我,但在那之前,我想我必须接受这个作为必要的解决方案。是的,这也是我最后做的。遗憾的是,NHibernate并没有自动处理这个问题。如果有人知道任何其他解决方案(或者知道这个bug,如果它是一个bug,什么时候会被修复),请告诉我,但在此之前,我想我必须接受这个作为必要的解决方案。
<class name="Entity" table="[Entity]">
    <id name="Id" column="Id" type="Int32" unsaved-value="0">
        <generator class="hilo"/>
    </id>
</class>
[Test]
public void Can_add_new_case()
{
    var newCase = new Case();
    newCase.EntityCollection.Add(new Entity(), Roles.Role1);
    newCase.EntityCollection.Add(new Entity(), Roles.Role2);

    /* At which point I try to persist newCase and get an exception */
}
[Test]
public void Can_add_new_case()
{
    var newCase = new Case();
    var entity1 = new Entity();
    var entity2 = new Entity();
    newCase.EntityCollection.Add(entity1, Roles.Role1);
    newCase.EntityCollection.Add(entity2, Roles.Role2);

    Rhino.Commons.NHRepository<Entity> entityRepository = new NHRepository<Entity>();
    Rhino.Commons.NHRepository<Case> caseRepository = new NHRepository<Case>();

    using (UnitOfWork.Start())
    {
        entityRepository.SaveOrUpdate(entity1);
        entityRepository.SaveOrUpdate(entity2);
        caseRepository.SaveOrUpdate(newCase);
    }
}