Attaching custom data with your query

Problem

Sometimes it's necessary to attach some additional data with each query and use that data on query execution.

For example, user might want to specify some piece of text on the client-side and filter the result set on that text so only the rows that contains that text must be inlcuded in the result.

EasyQuery totally allows to implement such a scenario with minimal efforts.

Solution

Define beforeExecuteQuery handler on the client-side

To add some extra data you can use beforeExecuteQuery event handler which can be defined on view initialization:


var options = {
    .     .     .     .
	handlers: {
		beforeExecuteQuery = (options) => {
		    options.data = options.data || {};
			var filterInput = document.getElementById('dataFilter');
			options.data.filter = filterInput.value;
		};
	}
};

var view = new AdvancedSearchView();

view.init(options);

Now if you check in Developer Tools (on Network tab), each .../execute request now includes ad additional data object in the request payload.

Define custom EasyQueryManager on the server-side

Now to process this additional request data you can create your own implementation of EasyQueryManager and override its ExecuteQueryCore method.

Here is an example:

public class EasyQueryManagerSqlWithFilter : EasyQueryManagerSql
{
    public EasyQueryManagerSqlWithFilter(IServiceProvider services, EasyQueryOptions options) : base(services, options) 
	{      
    }

    protected override IEqResultSet ExecuteQueryCore(JObject options = null)
    {
        var filter = this.ClientData["filter"]?.ToString();

        var stringColumns = Query.Columns.Where(c => c.SystemType == typeof(string));
        if (!string.IsNullOrEmpty(filter) && stringColumns.Any()) {
            var conditions = Query.Root.Conditions.ToList();
            if (conditions.Any()) {
                Query.Root.Conditions.Clear();

                var mainConditions = Query.Root.AddConditionGroup(Query.Root.Linking);
                foreach (var condition in conditions) {
                    mainConditions.Conditions.Add(condition);
                }
            }
            var textFilterConditions = Query.Root.AddConditionGroup(Condition.LinkType.Any);
			foreach (var column in stringColumns) {
				textFilterConditions.AddSimpleCondition(column.Expr.Value, "Contains", filter);
			}
        }

        return base.ExecuteQueryCore(options);
    }
}

Here we just reconfigure our current query and add in it an additional condition group with a bunch of conditions like SomeColumns contains 'filter text'

Finally, you need to register your manager class on EasyQuery middleware initialization:

app.UseEasyQuery(options => {
    .    .    .    .
	options.UseManager<EasyQueryManagerSqlWithFilter>();
});