I don't think the LINQ provider supports this but you can query on
subtype using ICriteria:
.Add(Restrictions.Eq("class", type))
Hope that helps.
On Nov 12, 12:42 am, Sergey Lobko-Lobanovsky
<[email protected]> wrote:
> Hello folks, I'd like to solicit your opinion on an approach I've taken to
> implement Linq queries on subclass-mapped entities.
> I am using the latest NHibernate 3.0 RC (built from SVN)
>
> Here's my domain:
>
> public abstract class Achievement
> {
> public virtual string id { get; set; }
> public virtual string userId { get; set; }
> *public virtual string type { get; set; }*
> *public virtual string achievementType { get; set; }*
>
> public Achievement() {
> achievementType = GetType().Name;
>
> }
>
> public abstract void Combine(Achievement other);
>
> }
>
> public class CouponCountAchievement : Achievement
> {
> public virtual int purchasedCouponCount { get; set; }
>
> public override void Combine(Achievement other) {
> if(typeof(CouponCountAchievement) != other.GetType())
> throw new ArgumentOutOfRangeException("other", other.GetType(), "Can't
> combine this achievement with CouponCountAchievement");
> var otherA = (CouponCountAchievement) other;
>
> purchasedCouponCount += otherA.purchasedCouponCount;
>
> }
> }
>
> Note the *bold italic property*: it's the discriminator-value column, while
> the* bold property* is a queryable property. Here's the mapping:
>
> public class AchievementMap : ClassMap<Achievement>
> {
> public AchievementMap() {
> Id(x => x.id)
> .GeneratedBy.UuidHex("");
> Map(x => x.userId);
> Map(x => x.achievementType);
>
> DiscriminateSubClassesOnColumn("type");
>
> }
> }
>
> public class CouponCountAchievementMap : SubclassMap<CouponCountAchievement>
> {
> public CouponCountAchievementMap() {
> Map(x => x.purchasedCouponCount);
>
> }
> }
>
> Here's my query (it works, yeah -- finally solved at 2am local time, after
> trying hql and detached criteria :) )
>
> public void RecordAchievement(Achievement achievement, string playerId) {
> var session = _container.Resolve<ISession>();
> var q = session.Query<Achievement>()
> .Where(a =>
> a.achievementType == achievement.achievementType &&
> a.userId == playerId);
>
> var baseAchievement = q.FirstOrDefault() ?? achievement;
>
> baseAchievement.userId = playerId;
> session.SaveOrUpdate(baseAchievement);
>
> }
>
> You may wonder what the problem is. Well, simple as cake: I have to
> duplicate 'type' and 'achievementType' because I *can't run Linq queries on
> 'type'*! In order to see why, make the following changes to the above code:
>
> 1. Remove 'achievementType' from Achievement
> 2. Change the mapping in AchievementMap to map 'type' instead of
> 'achievementType'
> 3. Change the query to query on 'type' instead of 'achievementType'
> 4. Run and observe the following exception at the end of the message.
>
> I really don't know whether this is an intended behavior or a bug, but in
> any case it should be somehow preventable because the exception itself
> doesn't bear any relationship to the real problem with the above code.
>
> System.ArgumentOutOfRangeException : Index was out of range. Must be
> non-negative and less than the size of the collection.
>
> Parameter name: index
>
> at System.ThrowHelper.ThrowArgumentOutOfRangeException()
>
> at System.Collections.Generic.List`1.get_Item(Int32 index)
>
> at Npgsql.NpgsqlParameterCollection.get_Item(Int32 index) in
> C:\projects\Npgsql2\src\Npgsql\NpgsqlParameterCollection.cs: line 117
>
> at Npgsql.NpgsqlParameterCollection.GetParameter(Int32 index) in
> C:\projects\Npgsql2\src\Npgsql\NpgsqlParameterCollection.cs: line 494
>
> at System.Data.Common.DbParameterCollection.
> System.Collections.IList.get_Item(Int32 index)
>
> at NHibernate.Type.AbstractStringType.Set(IDbCommand cmd, Object value,
> Int32 index) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Type\AbstractStringType.cs:
> line
> 17<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CType%5CAbstractStringType.cs%3F17%3F1>
>
> at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value,
> Int32 index) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Type\NullableType.cs:
> line
> 180<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CType%5CNullableType.cs%3F180%3F1>
>
> at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value,
> Int32 index, ISessionImplementor session) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Type\NullableType.cs:
> line
> 139<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CType%5CNullableType.cs%3F139%3F1>
>
> at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id,
> Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][]
> includeColumns, Int32 table, IDbCommand statement, ISessionImplementor
> session, Int32 index) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:
> line
> 2415<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CPersister%5CEntity%5CAbstractEntityPersister.cs%3F2415%3F1>
>
> at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id,
> Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object
> obj, ISessionImplementor session) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:
> line
> 2665<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CPersister%5CEntity%5CAbstractEntityPersister.cs%3F2665%3F1>
>
> at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id,
> Object[] fields, Object obj, ISessionImplementor session) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:
> line
> 3015<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CPersister%5CEntity%5CAbstractEntityPersister.cs%3F3015%3F1>
>
> at NHibernate.Action.EntityInsertAction.Execute() in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Action\EntityInsertAction.cs:
> line
> 59<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CAction%5CEntityInsertAction.cs%3F59%3F1>
>
> at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Engine\ActionQueue.cs:
> line
> 136<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CEngine%5CActionQueue.cs%3F136%3F1>
>
> at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Engine\ActionQueue.cs:
> line
> 126<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CEngine%5CActionQueue.cs%3F126%3F1>
>
> at NHibernate.Engine.ActionQueue.ExecuteActions() in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Engine\ActionQueue.cs:
> line
> 169<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CEngine%5CActionQueue.cs%3F169%3F1>
>
> at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(
> IEventSource session) in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:
> line
> 241<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CEvent%5CDefault%5CAbstractFlushingEventListener.cs%3F241%3F1>
>
> at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent
> event)
> in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:
> line
> 19<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CEvent%5CDefault%5CDefaultFlushEventListener.cs%3F19%3F1>
>
> at NHibernate.Impl.SessionImpl.Flush() in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Impl\SessionImpl.cs:
> line
> 1479<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CImpl%5CSessionImpl.cs%3F1479%3F1>
>
> at NHibernate.Transaction.AdoTransaction.Commit() in
> C:\_Projects\KupiKupon\kupikupon-server\lib-src\nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:
> line
> 187<about:file%3AC%3A%5C_Projects%5CKupiKupon%5Ckupikupon-server%5Clib-src%5Cnhibernate%5Csrc%5CNHibernate%5CTransaction%5CAdoTransaction.cs%3F187%3F1>
>
> *
> *
>
> at net.maygem.kupikupon.tests.AchievementTests.
> RecordFirstAchievementShouldCreateANewEntryInDB() in
> AchievementTests.cs: line 55
>
> <about:projectfile%3AF0D00249-84B1-4394-8AEC-CABA6A4FFA3C%2Fd%3A%23tests%2Ff%3AAchievementTests.cs%3F55%3F1>
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.