不确定这是否与我们最近升级到NHibernate 3.1(现在为3.2)有关,但对组件列表的查询不再选择正确的标识符。
ClassMap如下所示:
public class FilingMap : ClassMap<Filing>
{
public FilingMap()
{
Id(x => x.Id).GeneratedBy.Assigned();
Map(x => x.AcceptedOn);
Map(x => x.FiledBy).Not.Nullable();
Component(x => x.FiledByEmail, m => m.Map(c => c.Value, "FiledByEmail"));
Map(x => x.ConfirmationValue, "Confirmation");
HasMany(x => x.History)
.Table("FILING_HISTORY")
.AsList(p => p.Column("Idx"))
.Component(c =>
{
c.Map(x => x.Status);
c.Map(x => x.Timestamp);
c.Map(x => x.Message);
})
.Cascade.All().Access.CamelCaseField(Prefix.Underscore);
HasMany(x => x.Documents)
.Table("FILING_DOCUMENT")
.Component(c =>
{
c.Map(x => x.Image).CustomSqlType("BLOB");
c.Map(x => x.Name);
c.Map(x => x.Type, "FileType");
c.Map(x => x.NumberOfPages);
})
.Cascade.All().Access.CamelCaseField(Prefix.Underscore);
DiscriminateSubClassesOnColumn("Type");
}
}
精简的hbm看起来就在这里:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="Core.Filings.Filing, Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Filing`">
<id name="Id" type="System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="assigned" />
</id>
<discriminator type="String">
<column name="Type" />
</discriminator>
<list access="field.camelcase-underscore" cascade="all" name="History" table="FILING_HISTORY">
<key>
<column name="Filing_id" />
</key>
<index>
<column name="Idx" />
</index>
<composite-element class="Core.Filings.FilingStatusChange, Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<property name="Status" type="FluentNHibernate.Mapping.GenericEnumMapper`1[[Core.Filings.FilingStatus, Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], FluentNHibernate, Version=1.3.0.717, Culture=neutral, PublicKeyToken=8aa435e3cb308880">
<column name="Status" />
</property>
<property name="Timestamp" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Timestamp" />
</property>
<property name="Message" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Message" />
</property>
</composite-element>
</list>
</class>
</hibernate-mapping>
linq查询是这样的:
using(var session = sessionfactory.OpenSession())
{
Assert.DoesNotThrow(() => session.Query<Filing>()
.Where(x => x.History.Any(h => h.Status == FilingStatus.Error)).ToList());
}
删节的sql输出在这里:
select filing0_.Id as Id2_, filing0_.AcceptedOn as AcceptedOn2_,
...
from FILING filing0_
left outer join ...
where (exists
(select history1_.Id from FILING_HISTORY history1_ where filing0_.Id=history1_.FILING_ID
and history1_.Status=:p0)) and not (exists (select history2_.Id from FILING_HISTORY history2_
where filing0_.Id=history2_.FILING_ID and history2_.Status=:p1))
问题是默认键列(例如,entitytable_id)未在exists子查询中使用。相反,它使用实体可能具有的“id”列名称。即,应该是'Filing_id',而不是'Id'。
关于这可能是什么/在哪里的任何想法,或者它为什么有效,但现在却没有?谢谢!