Webpages, NHibernate and LoadForCriteria

For general questions and discussions specific to the AbleCommerce GOLD ASP.Net shopping cart software.
Post Reply
sloDavid
Lieutenant Commander (LCDR)
Lieutenant Commander (LCDR)
Posts: 92
Joined: Thu Feb 25, 2010 12:34 pm

Webpages, NHibernate and LoadForCriteria

Post by sloDavid » Fri Jan 25, 2013 9:31 pm

I'm not familiar with NHibernate, and I'm having trouble finding documentation about how to create an NHibernate session. I want to use WebpageDataSource.LoadForCriteria. Supposedly, I can create ICriteria objects from an instantiated NHibernate session object, but I can't figure out how to create one of those. Anybody know?

Ultimately, I'm just trying to get a list of Webpages in a particular given category, but that's proving to be far more challenging than expected. (Speaking of which, why is there no LoadForCategory method, like with ProductDataSource and CategoryDataSource?)

User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

Re: Webpages, NHibernate and LoadForCriteria

Post by jmestep » Sat Jan 26, 2013 9:50 am

Here one way you can create a session in Able:

Code: Select all

 ISession session = AbleContext.Current.Database.GetSession();
Webpages in Gold are confusing- the table has entries for 3 different types of webpages.
A webpage that is a placeholder for something like a category (Category Grid (Deep Item Display) is a webpage type of 1
A webpage that is a placehoder fora product page is a webpage type of 2
A webpage entry for something like home page is a webpage type of 0
A webpage you create in the admin to display data is a webpage type of 0
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

User avatar
mazhar
Master Yoda
Master Yoda
Posts: 5084
Joined: Wed Jul 09, 2008 8:21 am
Contact:

Re: Webpages, NHibernate and LoadForCriteria

Post by mazhar » Mon Jan 28, 2013 4:05 am

sloDavid wrote:I'm not familiar with NHibernate, and I'm having trouble finding documentation about how to create an NHibernate session. I want to use WebpageDataSource.LoadForCriteria. Supposedly, I can create ICriteria objects from an instantiated NHibernate session object, but I can't figure out how to create one of those. Anybody know?

Ultimately, I'm just trying to get a list of Webpages in a particular given category, but that's proving to be far more challenging than expected. (Speaking of which, why is there no LoadForCategory method, like with ProductDataSource and CategoryDataSource?)
You don't have to deal with session by yourself just use helper class CommerceBuilder.DomainModel.NHibernateHelper or alternativly you can directly access the session how Judy explained. Here is the sample usage of helper class

Code: Select all

NHibernate.ICriteria criteria = CommerceBuilder.DomainModel.NHibernateHelper.CreateCriteria<CommerceBuilder.Catalog.Webpage>();

User avatar
AbleMods
Master Yoda
Master Yoda
Posts: 5170
Joined: Wed Sep 26, 2007 5:47 am
Location: Fort Myers, Florida USA

Re: Webpages, NHibernate and LoadForCriteria

Post by AbleMods » Wed Jan 30, 2013 7:37 am

I have the same problem. nHibernate just complicates things imho and there's almost no documentation of how Able Gold has implemented it. So we're left with begging for scraps of wisdom or hoping someone else solved the problem for us AND had the courage to post it in a public forum.

Working examples speak volumes to me. Here's an example of how my Quickbooks module pulls Order data using nHibernate criteria. Based on what I've seen thus far in Gold, this concept will work with all the Able datasource classes.

First you must have the correct references at the top of your page. I always use:

Code: Select all

using CommerceBuilder.DomainModel;
using NHibernate;
using nhc = NHibernate.Criterion;
Why do I always use that? Because that's what I was told. I have no clue why every single page in a data-driven software application still has to manually include references to the data access engine. You'd think it would be included by default. /shrug

Once you've got the correct references, now you're ready to build a criteria object. The criteria object holds all the search rules you want to pass to nHibernate. Again this structure should work for most every able data object class. So if you want to do this on a different object class, just change <Order> to <ClassName>.

Code: Select all

            NHibernate.ICriteria criteria = NHibernateHelper.CreateCriteria<Order>();
Now you've got a criteria object, but nothing else. So we need to add some rules to the object. nHibernate probably calls them something else. I call them rules. The first rule I use is global i.e. it applies to the entire query.

Code: Select all

            criteria.Add(nhc.Restrictions.Eq("Exported", false));
So the above statement is the equivalent SQL of "SELECT * FROM ac_Orders WHERE Exported = false"

The nhc.Restrictions is where the action occurs. .Eq means "EQUAL". There are plenty of others and you can google for examples. I liked this page because it compared nHibernate queries to the actual generated SQL for easy reference: http://ayende.com/blog/4023/nhibernate-queries-examples

Now that I know I've included all orders with Exported = false, I add a few conditional rules based on configuration settings in my Quickbooks module. Note how the rules are added as items in a collection.

nHibernate discriminates OR and AND with using CONJUNCTION and DISJUNCTION. The default is CONJUNCTION (AND), so if you don't load the rule into a DISJUNCTION then it's going to assume it's an AND relationship. Lovely terminology eh?

This example below shows how I load both an AND relationship and optionally load both an additional AND with an OR relationship using the DISJUNCTION (case 2:).

Code: Select all


            // check store setting for respecting paid/shipped flags
            switch (ConfigSettings.RespectPayShip)
            {
                case 0: // when placed
                    break;
                case 1: // when paid
                    criteria.Add(nhc.Restrictions.Eq("PaymentStatusId", (byte)2));
                    break;
                case 2: // when paid and shipped
                    criteria.Add(nhc.Restrictions.Eq("PaymentStatusId", (byte)2));
                    criteria.Add(nhc.Restrictions.Disjunction()
                        .Add(nhc.Restrictions.Eq("ShipmentStatusId", (byte)2))
                        .Add(nhc.Restrictions.Eq("ShipmentStatusId", (byte)3))
                        );
                    break;
            }
Finally, you are ready to run the actual query. That part is simple.

Code: Select all

            // execute your query
            IList<Order> _Orders = criteria.List<Order>();
There's no doubt that the implementation of nHibernate complicates things. And it makes the exception errors look enormous and difficult to interpret. Hopefully Able will start posting some working code examples to give everyone a chance to succeed with their own customizations.

I hope this helps you along with your project.
Joe Payne
AbleCommerce Custom Programming and Modules http://www.AbleMods.com/
AbleCommerce Hosting http://www.AbleModsHosting.com/
Precise Fishing and Hunting Time Tables http://www.Solunar.com

User avatar
Logan Rhodehamel
Developer
Developer
Posts: 4116
Joined: Wed Dec 10, 2003 5:26 pm

Re: Webpages, NHibernate and LoadForCriteria

Post by Logan Rhodehamel » Wed Jan 30, 2013 11:37 am

Not having a LoadForCategory method for webpages is unfortunate. I've logged a task to get that added. Implementing this query as a first experience with NHibernate might be frustrating. It involves two different tables. To help you along I've implemented this custom class:
WebpageHelper.cs.txt
This would be placed in either your Code or App_Code directory. Then you can call WebpageHelper.LoadForCategory. It has all the same options implemented as for Products.

Inside the file you will see the code makes use of something called a DetachedCriteria. This is a way of making a subquery that we use to examine the category structure (especially required if you want to recurse into the category tree).

NHibernate has a bit of a learning curve when you get into custom queries. Some of it is learning the terminology (of which Joe is a fan) and some of it is learning the syntax. There is also another thread floating about that shows how you can bypass most of the NHibernate stuff and run a straight SQL query.
Cheers,
Logan
Image.com

If I do not respond to an unsolicited private message, it's not because I'm ignoring you. It's because the answer to your question is valuable to others. Try the new topic button.

sloDavid
Lieutenant Commander (LCDR)
Lieutenant Commander (LCDR)
Posts: 92
Joined: Thu Feb 25, 2010 12:34 pm

Re: Webpages, NHibernate and LoadForCriteria

Post by sloDavid » Thu Feb 21, 2013 11:58 am

To anyone else looking for another simple way of doing this, you normally won't need Webpage-specific fields, but I found it also possible to achieve the objective simply using CatalogNodes:

Code: Select all

CategoryDataSource.Load(categoryId).CatalogNodes.Where(cn => (cn.CatalogNodeType == CatalogNodeType.Webpage))

Post Reply