numberwang
numberwang

Reputation: 313

NHibernate: Criteria/SubCriteria Projection

I have a class Mod, which has a member:

ICollection<Event> EventList

The class Event has a member:

public virtual EventType Type { get; set; }

The class EvenType has member:

   public virtual int Id

I want to get a list of all Events in Mod which have an id of 1 or 2 using NHibernate Criteria. I did this:

var subCriteria = DetachedCriteria.For<Mod>()
    .Add(Restrictions.In("Event.Type", new int[] {1, 2 })
    );
criteria.Add(Subqueries.Exists(subCriteria));

but I get a runtime error saying Cannot use subqueries on a criteria without a projection.

So, fine, but I don't know what to put for the Projection. I can find examples of how to do Projections, but nothing that really explains the purpose. I've tried various things, but all result in a runtime error:

Message : Value cannot be null. Parameter name: key Source : mscorlib Help link : ParamName : key

I need to use subquery because I will be adding more when this works.

Can you suggest what to do for Projection?

Upvotes: 4

Views: 6875

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

As documented here: 16.4. Associations it could be done like this:

IQueryOver<Mod, Event> query = session
  .QueryOver<Mod>()
  .JoinQueryOver<Event>(mod => mod.EventList)
  .WhereRestrictionOn(evnt => evnt.Type.Id).IsIn(new object[] { 1, 2});

var result = query.List<Mod>();

EDIT: pure Criteria API:

var criteria = session.CreateCriteria<Mod>();
var sub = criteria.CreateCriteria("EventList", JoinType.LeftOuterJoin);
    sub.Add(new InExpression("Type", new object[] { 1, 2 }));

var result = criteria.List<Mod>();

using detached criteria. In this case, the EventType must have property ModId or refernece to the Mod instance. In the subquery, we have to return list of valid Mod.IDs

var sub = DetachedCriteria
 .For<Event>()
 .Add(Restrictions.In("Type", new int[] {1, 2 })) // WHERE
 .SetProjection(Projections.Property("ModId")); // Mod.ID the SELECT clause

var criteria = session.CreateCriteria<Mod>();
criteria.Add(Subqueries.PropertyIn("ID", sub)); // Mod.ID in (select
var result = criteria.List<Mod>();

Upvotes: 7

Related Questions