This project is read-only.

N2.Find.Items

Topics: Developer Forum
Jan 15, 2009 at 12:35 PM
Is it possible to do a query like:

 ItemFilter filter = new ParentFilter(this);
return N2.Find.Items
            .Where.Type.Eq(typeof(EventItem))
            .And.Detail("FirstDate").Ge(DateTime.Now.Date)
            .Filters(filter)
            .OrderBy.Detail("FirstDate").Asc
            .MaxResults(maxEvents)
            .Select<EventItem>();

Where "FirstDate" is a property that just fetches the first item in a "Dates" collection that is stored in the n2CMS.
Basically "FirstDate" does not itself call "GetDetail", "SetDetail", but "Dates" does.

For the moment I have changed the code to
ItemFilter filter = new ParentFilter(this);
        return N2.Find.Items
            .Where.Type.Eq(typeof(EventItem))
            .Filters(filter)
            .Select<EventItem>()
            .OrderBy(e => e.FirstDate)
           .Take(maxEvents);

I'm guessing that this N2 querying is doing something with NHibernate? And maybe doing the filtering in the database level? If so it will have no concept of "FirstDate".

FirstDate just calles Dates.First();

Is there a way to query the heirachy through Detail("Dates[0]")?

Would it be possible to do something like N2.Find<EventItem>.Where.FirstDate.Ge(DateTime.Now.Date).Select();?
I.e. rather than having to work with ContentItem to allow working with just one type of item.
Not sure if using LinqToSql would help with this or not rather than Nhibernate?

I'm sure there are lots of reasons for how it works, just trying to get an understanding and any potential limitations.

Another idea would be to persist the objects to a object database like DB4O, but you have done a pretty good job keeping to only 4 database tables.

Look forward to finding out some more about advanced querying.

Regards

Jan 15, 2009 at 11:29 PM
The Detail method searches through both details and detail collection so I think you could .do it like this:

return N2.Find.Items
            .Where.Type.Eq(typeof(EventItem))
            .And.Detail("Date").Ge(DateTime.Now.Date)
            .Filters(filter)
            .OrderBy.Detail("FirstDate").Asc
            .MaxResults(maxEvents)
            .Select<EventItem>();

What's going on under the hood is that a hql query is generated and passed to nhibernate that does all the advanced stuff. Linq to sql could also work. You'd have to live with not re-using the N2 content item.

Another possible option would be writing your own query using NHibernate's criteria or HQL API:S or using linq to nhibernate.
Jan 16, 2009 at 9:30 AM
Thanks for the reply, but if this is producing a hql query (I presume like sql, i.e. database level), and the property "FirstDate" has to be in n2cms this isn't going to work, as "FirstDate" is only defined on the type EventItem and is not stored in n2cms as it is a calculated field.
Also rather than just being a simple "Date", I have a property "Dates" which is an EventDayCollection which stores EventDay's.
I think this is getting stored as binary.
So unless the N2.Find.Items works on reflection, which means it would have to load back all the data anyway, this isn't going to work. (Think I have answered my own question here, as this is the same as the query that I came up with using Linq rather than the N2.Find.Items).

Maybe when saving the EventItem it could store the calculated field in the N2cms for retrival purposes only, this calculated field will only change when the Dates collection changes so can just save it after saving this collection. But if there was a calculated field that relied on something else, like the current time, then the query would have to be done outside N2.Find.Items.

I'd be interested to see an implementation of n2cms that used an object database to see if this allowed for advanced querying without having to load all the objects back to be able to do reflection on them.

Jan 16, 2009 at 9:55 AM
Having stored "FirstDate" in the n2cms the following now works

        ItemFilter filter = new ParentFilter(this);
        return N2.Find.Items
            .Where.Type.Eq(typeof(EventItem))
            .And.Detail("FirstDate").Ge(DateTime.Now.Date)
            .Filters(filter)
            .OrderBy.Detail("FirstDate").Asc
            .MaxResults(maxEvents)
            .Select<EventItem>();