Views: 2542
Number of votes: 0
Average rating:

Metadata-driven Community queries

First step was to make my Community site sync entity attributes automatically which is described here.

When I added support for searching and other stuff in my site which requires a lot of queries, I noticed that I do not have metadata driven support for queries.

So currently I need to write something like this to query something:

 

var query = new UserQuery();
var stringCriterion = new StringCriterion
    {
        Value = "12345",
        WildCardType = WildCardType.Both
    };
query["OrgCode"] = stringCriterion;

 

Next step was to make use that strongly-typed approach here as well.

For this we need to extend FrameworkEntityQueryBase class to add support for “converting” it to our known metadata class.

So we need to add new method named AsMetadataQuery as following:

 

public static MetadataFrameworkEntityQuery<T> AsMetadataQuery<T>(this FrameworkEntityQueryBase query) where T : class
{
    if (query == null)
    {
        throw new ArgumentNullException("query");
    }

    return new MetadataFrameworkEntityQuery<T>(query);
}

 

It returns back MetadataFrameworkEntityQuery class that has generic type parameter of entity attribute definition class.

Class itself is pretty simple:

 

public class MetadataFrameworkEntityQuery<T>
{
    public FrameworkEntityQueryBase Query { get; private set; }

    public MetadataFrameworkEntityQuery(FrameworkEntityQueryBase query)
    {
        Query = query;
    }

    public ICriterion this[Expression<Func<T, object>> epxr]
    {
        get
        {
            var helper = new ExpressionHelper();
            var propertyName = helper.ExtractMemberAccess(epxr);

            return Query[propertyName];
        }

        set
        {
            var helper = new ExpressionHelper();
            var propertyName = helper.ExtractMemberAccess(epxr);

            Query[propertyName] = value;
        }
    }
}

 

It just overwrites indexer to provide Expression for pointing to some of the attribute name. It uses helper method to find MemberAccess expression body within the expression.

After implementing this now we are able to write something like this:

 

var query = new UserQuery();
var stringCriterion = new StringCriterion
    {
        Value = "12345",
        WildCardType = WildCardType.Both
    };

var metadataQuery = query.AsMetadataQuery<UserMetadata>();
metadataQuery[m => m.OrgCode] = stringCriterion;

 

It would be nice also to have support for other members for the type you get back from AsMetadataQuery() method. Currently this is not supported and back you get only class that provides metadata-driven indexer. Will see what we can do for the next version.

As usual – package could be found in nuget.episerver.com. Name for the package – “Geta.Community.EntityAttributeBuilder”.

 

 

Hope this helps!

Feb 10, 2012

Please login to comment.