Linq for NHibernate奇怪的Count()行为

时间:2010-07-13 03:38:27

标签: linq-to-nhibernate

我有一个让我感到震惊的是Linq for NHibernate的一个非常不寻常的行为。

通常,我的所有实体类都运行得很好,但是其中一个在以下条件下从NHibernate命名空间抛出“NonUniqueResult”异常。

如果我打电话给以下人员:

getSession<MyClass>().Linq<MyClass>().Count();

它抛出异常。如果我打电话

getSession<MyClass>().Linq<MyClass>().ToList().Count();

它没有。

这个类的其他CRUD操作没有问题,所以我不认为这是我的映射。

我的猜测是,它与Count()运算符最终如何实现为SQL查询有关,但除此之外,我不确定在哪里查看。

已更新,以包含相关课程的映射

<?xml version="1.0" encoding="utf-16"?>
<hibernate-mapping  auto-import="true" default-lazy="false" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
  <class name="My.App.MyClass, My.App" table="MyClass">
<id name="Id" access="property" column="Id" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
  <generator class="guid.comb">
  </generator>
</id>
<version name="TimeStamp" access="property" column="TimeStamp" type="Int32" />
<property name="CreatedOn" access="property" type="System.DateTime">
  <column name="CreatedOn"/>
</property>
<property name="Ticker" access="property" type="Int32">
  <column name="Ticker"/>
</property>
<property name="DifferentTicker" access="property" type="Int32">
  <column name="DifferentTicker"/>
</property>
<property name="SomeDecimal" access="property" type="System.Decimal">
  <column name="SomeDecimal"/>
</property>
<property name="StillAnotherTicker" access="property" type="Int32">
  <column name="StillAnotherTicker"/>
</property>
<property name="IsActive" access="property" type="Boolean">
  <column name="IsActive"/>
</property>
<many-to-one name="RelatedThing" access="property" class="My.App.RelatedThing, My.App" column="RelatedThingId" lazy="proxy" />
<many-to-one name="OtherRelatedThing" access="property" class="My.App.OtherRelatedThing, My.App" column="OtherRelatedThingId" lazy="proxy" />
<bag name="_schedule" access="property" table="Schedule" lazy="false" cascade="all-delete-orphan">
  <key column="MyClassId" />
  <one-to-many class="My.App.Schedule, My.App" />
</bag>
<bag name="Vectors" access="property" table="Vectors" lazy="false">
  <key column="MyClassId" />
  <many-to-many class="My.App.Channels.BaseVector, My.App" column="vectorid"/>
</bag>
</class>
</hibernate-mapping>

1 个答案:

答案 0 :(得分:0)

在简单的单元测试中,这两个版本都适用于我。在这个例子中:

using ( var tx = Session.BeginTransaction() )
{
    int count = Session.Linq<Customer>().Count();
    Assert.Equal( 2, count );

    count = Session.Linq<Customer>().ToList().Count();
    Assert.Equal( 2, count );

    tx.Commit();
}

第一个查询执行SQL计数:

NHibernate: SELECT count(*) as y0_ FROM "Customer" this_

第二个获取all将所有项返回到临时列表中,然后在列表中调用Count():

NHibernate: SELECT this_.Id as Id9_0_, this_.Name as Name9_0_ FROM "Customer" this_

这让我相信你的映射可能存在问题。而且你真的想要让第一个工作正常,因为第二个不能扩展到大型数据集。