Question

I have a table with many records in it which can be filtered by rowstatus, created date, modifieddate.

I am using fluent nhibernate as the ORM.

Now the request that can come in the WebAPi can be:

?rowstatus=0 OR ?rowstatus=0&createddate=05-30-2013 OR createddate=05-30-2013 OR modifieddate=05-29-2013&rowsstatus=0

as you can see any combination of filters can come in into the query string.

I wanted to know, how can I dynamically build a list of criteria and give it to my ISession object to execute. what is the best way to do it.

Currently I have so many overloaded functions to do it and it is ugly. Here is an example of what I am using. I want to inject dynamically rowstatus and createddate.

_session.QueryOver<ApiData>()
                           .Where(a => (a.status== rowstatus)
                                       && (a.createdDate== createddate)).List().ToList();
Was it helpful?

Solution 2

This is how I finally did it:

        var status = queryParams.FirstOrDefault(q => q.Key == "status").Value;
        var entity = queryParams.FirstOrDefault(q => q.Key == "entity").Value;
        var start = queryParams.FirstOrDefault(q => q.Key == "start").Value;

        if(!string.IsNullOrEmpty(status))
        {
            query.Where(r => r.RowStatus == Convert.ToInt32(status));
        }
        if (!string.IsNullOrEmpty(entity))
        {
            query.Where(r => r.EntityType == entity);
        }

        //Ensure that this should be the last filter criteria to be applied
        if (!string.IsNullOrEmpty(start))
        {
            query.Skip(Convert.ToInt32(start));
        }

        var count = query.RowCount();

        var results = query.Take(apiUser.ApiLimit).List().Select(c => _cryptography.Decrypt(c.Json)).ToList();

OTHER TIPS

I use nHibernate Criteria queries for this type of scenario as they are extremely flexible and you can build them up as you go depending on the search parameters that are supplied.

I have created a basic example for you below based on some of the criteria you specified in your question, you should be able to modify my example to suit your specific needs.

public IList<ApiData> SearchApiData(int? rowStatus, DateTime? createdDate)
{

        ICriteria query = _session.CreateCriteria<ApiData>();

        if (rowStatus.HasValue)
        {
            query.Add(Restrictions.Eq("RowStatus", rowStatus.Value));
        }

        if (createdDate.HasValue)
        {
            query.Add(Restrictions.Eq("CreatedDate", createdDate.Value));
        }

        return query.List<ApiData>();

}

Also when I have many search parameters I normally create a class structure to enable me to pass them around my application in your case something like:

public class ApiDataCriteria{

     public int? RowStatus {get;set;}
     public DateTime? Created {get;set;}
     public DateTime? Modified {get;set;}

}

Populate this according to your current search criteria (most likely based on user selection in the UI) then pass into the method I created above like this:

public IList<ApiData> SearchApiData(ApiDataCriteria criteria)
{

        ICriteria query = _session.CreateCriteria<ApiData>();

        if (criteria.rowStatus.HasValue)
        {
            query.Add(Restrictions.Eq("RowStatus", criteria.rowStatus.Value));
        }

        if (criteria.createdDate.HasValue)
        {
            query.Add(Restrictions.Eq("CreatedDate", criteria.createdDate.Value));
        }

        return query.List<ApiData>();

}

That way you only need a single method whose signature won't change even if you add more search criteria later on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top