Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用自定义生成器级联保存nhibernate实体时堆栈溢出_C#_Nhibernate_Hibernate - Fatal编程技术网

C# 使用自定义生成器级联保存nhibernate实体时堆栈溢出

C# 使用自定义生成器级联保存nhibernate实体时堆栈溢出,c#,nhibernate,hibernate,C#,Nhibernate,Hibernate,我是Nhibernate的新手,所以为冗长的描述道歉 我怀疑改变遗留数据库的结构可能是最好的选择,但我想尝试让NHibernate来处理它 基本上,结构是端点有地址和联系人。端点存储在具有复合ID(地址ID、联系人ID)的表中 级联保存地址时出现问题,该地址具有自定义ID生成器-地址ID的形式为“ADR000234”,以适应遗留数据库结构 自定义ID生成器包含一个查询,当我将地址保存为端点的一部分时,会出现堆栈溢出。当调试光标到达计算查询的行(var maxAddressID..)时,然后跳回到

我是Nhibernate的新手,所以为冗长的描述道歉

我怀疑改变遗留数据库的结构可能是最好的选择,但我想尝试让NHibernate来处理它

基本上,结构是端点有地址和联系人。端点存储在具有复合ID(地址ID、联系人ID)的表中

级联保存地址时出现问题,该地址具有自定义ID生成器-地址ID的形式为“ADR000234”,以适应遗留数据库结构

自定义ID生成器包含一个查询,当我将地址保存为端点的一部分时,会出现堆栈溢出。当调试光标到达计算查询的行(var maxAddressID..)时,然后跳回到方法的开头,并继续这样做,直到引发堆栈溢出

这是我的发电机课

public class AddressIdGenerator :  IIdentifierGenerator
{
    public object Generate(ISessionImplementor session, object obj)
    {
        var castAsSession = (ISession)session;
        var allAddresses = castAsSession.CreateQuery("select max(Code) from Address a");
        var maxAddressID = (string)allAddresses.List()[0];
        var previousNumber = int.Parse(maxAddressID.Substring(3, 6));

        return GetNewId("ADR", previousNumber);
    }

    private string GetNewId(string prefix, int number)
    {
        return prefix + (number + 1).ToString().PadLeft(6, '0');
    }
}
下面是我对EndPoint类的映射

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="DataClasses"
    namespace="DataClasses">
    <class name="EndPoint" table="[Addresses_Contacts]">
    <composite-id>
    <key-property name ="Address" column ="[Address ID]" type="string" />
    <key-property name ="Contact" column ="[Contact ID]" type="string"/>
    </composite-id>

    <many-to-one name="Address" class="DataClasses.Address, DataClasses" cascade="save-update"/>
    <many-to-one name="Contact" class="DataClasses.Contact, DataClasses" cascade="save-update"/>

    </class>
    </hibernate-mapping>

以及地址的映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataClasses" namespace="DataClasses">
<class name="Address" table="[Lookup Addresses]" >
<id name="Code" column="ID" type="string">
  <generator class="Nhibernate.AddressIdGenerator, Nhibernate" />
</id>
<property name="OrganisationName" column="[Name of Organisation]"/>
<property name="StreetAddress1" column="[Park/centre/estate]" />
<property name="StreetAddress2" column="[Street Name]" />
<property name="Town" column="[Town/City]" />
<property name="State" column="[Region/ State]" />
<property name="PostCode" column="[Postal/ Area Code]" />
<property name="District" column="[Local District]" />
<property name="Airport" column="[Airport code]" />
<many-to-one name="Country" class="DataClasses.Country, DataClasses" column ="[Country Code]"/>
</class>
</hibernate-mapping>

如果我尝试自己保存和寻址,它工作正常,生成的ID没有问题

另外,如果我从映射中删除地址和联系人属性(但不是从复合ID中),并在保存端点之前保存地址和联系人,也可以


在我看来,当我执行级联保存时,由于某种原因,它无法在过程中运行其他查询,但它没有抛出异常,而是行为异常(一次又一次地重新启动该方法)。我以前从未见过C#方法能做到这一点。我很想知道是否有人知道如何解决这个问题。

我认为问题在于您正在生成器中执行nh查询,并且您正在查询要保存的实体类型

不是在调用Save()时调用生成器,而是在需要刷新/提交数据时调用生成器。现在,Save()将实体放在一个操作队列中,该队列包含要执行的操作。当您调用CreateQuery/CreateCriteria并通过List()/UniqueResult()请求结果时,nhibernate的引擎检测到您对某个实体发出了Save()请求,因此将首先尝试刷新/提交该实体(从而调用生成器),然后执行查询,从而启动无限循环;逻辑是这样的,因为您调用了Save(),然后查询该类类型,所以您希望结果集包含保存的对象


因此,用本机SqlCommand替换您的Nh查询(CreateSqlQuery也可以工作),我认为您的问题将得到解决。

请在端点xml映射中更新关系的所有者。 请在地址和联系人的多对一中提及inverse=“true”。
谢谢

你能发布地址映射吗?我有一个确切的问题。你能告诉我你是怎么解决的吗?我尝试了CreateSQLQuery(),但收到了相同的StackOverFlow异常。我没有尝试本机SqlCommand方法..是的,因为在FlushMode.Auto上,CreateSqlQuery也可能引发刷新,从而导致问题。您必须使用本机SQLCommands,非常感谢您给我FlushMode提示。我添加了session.FlushMode=FlushMode.Commit;至少对我来说,stackoverflow问题消失了,一切正常。请注意,这意味着,当您时不时地保存实体A时,您进行了一个应返回实体A的查询,但它不会返回实体A(因为该实体尚未被持久化)