2010-07-13 3 views
0

У меня есть то, что поражает меня как очень необычное поведение Linq для NHibernate.Linq для NHibernate странное поведение Count()

В общем, все мои классы объектов работают нормально, но один из них выдает исключение «NonUniqueResult» из пространства имен NHibernate при следующем условии.

Если я вызываю следующее:

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> 

ответ

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_ 

И второй получает все возвращает все элементы во временный список, а затем вызывает Count() в списке:

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

Это заставляет меня думать, что может быть проблема с вашими сопоставлениями. И вы действительно хотите, чтобы первая работала, вторая не будет масштабироваться для больших наборов данных.

+0

Согласны на производительность удара. Я действительно не знаю, что это может быть на картировании, я добавил сопоставление класса в вопросе выше, если вы это видите. Я использую ActiveRecord для выполнения сопоставлений, так вот что он создал. И снова, не видя ошибок в других классах, и этот работает отлично для всех других операций. –

+0

Но ошибка не имеет ничего общего с Count(), поскольку она не является частью SQL. Я предполагаю, что вы получите ту же ошибку с "getSession () .Linq () .ToList()"? –

Смежные вопросы