Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/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
nHibernate-存储过程和复合密钥_Nhibernate_Stored Procedures_Composite Key - Fatal编程技术网

nHibernate-存储过程和复合密钥

nHibernate-存储过程和复合密钥,nhibernate,stored-procedures,composite-key,Nhibernate,Stored Procedures,Composite Key,我正在尝试使用nHibernate将存储过程的输出映射到项目中的对象 对象如下所示: public class NewContentSearchResult { public string Name { get; set; } public string ContentType { get; set; } public int Count { get; set; } public int CMIId { get; set; } public int Fea

我正在尝试使用nHibernate将存储过程的输出映射到项目中的对象

对象如下所示:

public class NewContentSearchResult
{
    public string Name { get; set; }
    public string ContentType { get; set; }
    public int Count { get; set; }
    public int CMIId { get; set; }
    public int FeatureId { get; set; }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Class.Assembly"
    namespace="Class.Assembly"
    default-lazy="false" default-cascade="none">
  <class name="NewContentSearchResult" mutable="false" check="none">
    <composite-id unsaved-value="none">
      <key-property name="CMIId" type="int" />
      <key-property name="FeatureId" type="int" />
    </composite-id>
    <property name="ContentType" type="string" />
    <property name="Name" type="string" />
    <property name="Count" type="int" />
  </class>
  <sql-query name="spWebGetNewContentBySalesRole">
    <return class="NewContentSearchResult" lock-mode="read">
      <return-property name="Name" column="Name" />
      <return-property name="ContentType" column="FeatureDesc" />
      <return-property name="Count" column="Number" />
      <return-property name="CMIId" column="CMIId" />
      <return-property name="FeatureId" column="FeatureId" />
    </return>
    exec core.spWebGetNewContentBySalesRole :SalesRoleId
  </sql-query>
</hibernate-mapping>
映射如下所示:

public class NewContentSearchResult
{
    public string Name { get; set; }
    public string ContentType { get; set; }
    public int Count { get; set; }
    public int CMIId { get; set; }
    public int FeatureId { get; set; }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Class.Assembly"
    namespace="Class.Assembly"
    default-lazy="false" default-cascade="none">
  <class name="NewContentSearchResult" mutable="false" check="none">
    <composite-id unsaved-value="none">
      <key-property name="CMIId" type="int" />
      <key-property name="FeatureId" type="int" />
    </composite-id>
    <property name="ContentType" type="string" />
    <property name="Name" type="string" />
    <property name="Count" type="int" />
  </class>
  <sql-query name="spWebGetNewContentBySalesRole">
    <return class="NewContentSearchResult" lock-mode="read">
      <return-property name="Name" column="Name" />
      <return-property name="ContentType" column="FeatureDesc" />
      <return-property name="Count" column="Number" />
      <return-property name="CMIId" column="CMIId" />
      <return-property name="FeatureId" column="FeatureId" />
    </return>
    exec core.spWebGetNewContentBySalesRole :SalesRoleId
  </sql-query>
</hibernate-mapping>
如果没有复合键(仅使用CMIId),它可以正常工作,除非有两个结果(如上所述)共享一个CMIId…第二个结果被第一个结果覆盖

我必须使用复合键,CMIId/FeatureId是逻辑组合

当我现在运行此操作时,会出现一个异常:

NHibernate.ADOException: could not execute query
[ exec core.spWebGetNewContentBySalesRole ? ]
  Name: SalesRoleId - Value: 266
[SQL: exec core.spWebGetNewContentBySalesRole ?] --->  System.IndexOutOfRangeException: CMIId22_0_.

在过去,当我使用复合键时,我总是必须为该ID创建一个单独的类,该类的属性与复合键的单独键匹配。您尝试过这个吗?

好的,进一步的研究使我确信,当您使用存储过程时,在nHibernate中不可能有复合ID


为此,我修改了我的SQL以包含rownumber(),并将其用作id。我只能这样做,因为它是只读的,没有写入数据库,但它符合我的目的。

今天有点晚了,但我可以再次标记Struzinski-这是可能的

我最近遇到了这个问题,通过为复合键使用单独的类并在映射中使用元素解决了它,如下所示

<sql-query name="spWebGetNewContentBySalesRole" >
    <return class="NewContentSearchResult">
        <return-property name="NewContentSearchResultKey">
            <return-column name="CMIIdColumn" />
            <return-column name="FeatureIdColumn" />
        </return-property>
        <return-property name="Name" column="Name" />       
        <return-property name="ContentType" column="FeatureDesc" />       
        <return-property name="Count" column="Number" />       
    </return>
    exec core.spWebGetNewContentBySalesRole :SalesRoleId 
</sql-query>

exec core.spWebGetNewContentBySalesRole:SalesRoleId

请注意,return column元素中的“name”属性表示结果集中的名称,并且应该与id类中的属性顺序相同。

正如在接受的答案中所提到的,我使用ROWNUM函数在Oracle中使用了唯一的行号hack。后来,我在使用不同的参数重用查询时遇到了一个问题。似乎nHibernate记住了ID,并希望将它们与新返回的结果相关联,从而返回不正确的行。我通过将行号与时间戳组合在一起修复了此问题,如下所示:

(ROWNUM * 10000000000 + dbms_utility.get_time) AS ROW_ID

这样,您就可以保证每次都能为查询结果获得全新的ID。只需确保使用足够大的整数来保存映射对象中的值。我在c#net中使用了一个8字节的
ulong
。您还可以从乘法器中取出几个0以缩短ID。

您可以发布生成的代码和映射吗?我正在尝试做同样的操作,但是我得到了一个错误。映射只是添加了一个不是复合id的“id”字段,SQL只是将“rownumber()作为id”作为第一个参数。谢谢,这对我来说很有效。我花了几个小时试图在单独的课堂上做这件事,但总是出错。在Oracle中使用了ROWNUM函数,效果非常好!