Complex Queries

Jan 22, 2010 at 9:44 AM

Specifications

I've been playing with Specifications in WCHM and for simple "queries" they seem to work really nicely.

By "simple" I mean queries where only one domain object is involved (e.g. return products where the productId equals 2).

However, a limitation surfaces when it comes to more complex queries.

For example, in a recent project we had a list of Resources, and Keywords.

These were joined via a many-to-many association (NHibernate maps the joining table so you end up with Resources, Keywords, ResourceKeywords).

Now if I want a list of resources by keyword, am I right in thinking a LinqSpecification can't handle this scenario?

Repositories

I know there's been some talk recently of avoiding dumping all of your query logic onto repositories, and instead keeping repositories as close as possible to a pseudo collection to which you can add/remove/retrieve objects.

The question is where to put this without compromising the existing architecture. I like specifications because the logic remains firmly in the domain.

However for this I would probably end up extending IResourceRepository and end up with an implementation something like...

 

    public class ResourceRepository : LinqRepository<Resource>, IResourceRepository
    {
        public IQueryable<Resource> ListByKeyword(int keywordId)
        {
            ICriteria criteria = Session.CreateCriteria<Resource>()
                .CreateAlias("Keywords", "keyword")
                .Add(Restrictions.Eq("keyword.id", keywordId))
                .SetResultTransformer(new DistinctRootEntityResultTransformer());

            return criteria.List<Resource>().AsQueryable();
        }
    }

Is there another way?

Thanks in advance

 

 

Developer
Mar 18, 2010 at 5:50 PM

Hi Jon,

It seems like you should be able to achieve this using Specifications.  Off the top of my head, the lambda you'd have inside your ResourceByKeywordSpecification would look something like this:

r => r.Keywords.Any(k => k.Id == keywordId)

I know I've done similar in the past and it's worked fine. We didn't have to resort to criteria on either WCHM or FancyDressOutfitters (and FDO has a number of many to many relationships). I've only just had to do it now, and that's to cover some low level infrastructure requirements rather than the kind of business rules we use the specifications for.

Cheers

Jon