Monthly Archives: July 2015

Dynamic predicates in C# using PredicateBuilder

One of the challenges I frequently encounter, is having to translate the arbitrary criteria in a testcase to LINQ selection predicates. Take the following very simple example testcase:

Feature: ModifyingInvoices
	In order to demonstrate the usefulness of PredicateBuilder, 
        we will show how to verify if a C# collection contains a
        record that matches multiple criteria that are only known 
        at run time

Scenario: ModifyDescription
	When I create an invoice with number '123' for '20' euro
	Then The systems invoice store must look like:
	| Number | Amount | DescriptionPresent | Desciption |
	| 123    | 20     | False              |            |
	When I change the description in invoice '123' to 'Testing!'
	Then The systems invoice store must look like:
	| Number | Amount | DescriptionPresent | Description |
	| 123    | 20     | True               | Testing!    |

In this very small example, you already see that the C# code will need to determine at run-time IF an invoice exists AND MAYBE what the contents of its description should be. If an invoice has many fields. this will become exponentially complex in the code. If your criteria requires an OR construct then that’s even more complex. The solution is to use a PredicateBuilder that builds a dynamic predicate

First install the NuGet Package LINQKit (see PredicateBuilder website) Then add the directive using LinqKit; to your code. Now create the code that queries your data like follows:

        [Then(@"The systems invoice store must look like:")]
        public void ThenTheSystemsInvoiceStoreMustLookLike(Table table)
        {
            var rows = table.CreateSet<InvoiceTest>();

            foreach(InvoiceTest test in rows)
            {
                var MyPredicate = LinqKit.PredicateBuilder.True<Invoice>();
                MyPredicate = MyPredicate.And(invoice => invoice.Number == test.Number);
                MyPredicate = MyPredicate.And(invoice => invoice.Amount == test.Amount);

                if (test.DescriptionPresent)
                {
                    MyPredicate = MyPredicate.And(item => item.Desciption.Equals(test.Description));
                }

                //Test that our datastore contains an invoice that matches the predicate from the testcase
                IQueryable<Invoice> Matches = this.Invoices.AsQueryable().Where<Invoice>(MyPredicate);
                Assert.AreEqual(1, Matches.Count());
            }
        }

What to do when your JQuery-ui dialog is hidden behind other elements

If you see your JQuery-ui dialog being hidden by other elements in the webpage, then you need to increase its z-index. I recently ran into the case where the JQXgrid widget was using very high z-indeces outside of my control.

Here’s the code:

ZIndexer = function () {
    var self      = this;
    this.Elements = [];
    
    this.Add = function (JQuerySelector) {
        var DomElementArray = $(JQuerySelector)
        $.each(DomElementArray, function (i, element) { self.Elements.push(element) })
        return this;
    }

    this.GetNextFreeZIndex = function () {
        var zIndeces = $(this.Elements).sort(function descending(a, b) {
            var bZIndex = $(b).zIndex()
            var aZIndex = $(a).zIndex()
            return bZIndex - aZIndex
        })

        return $(zIndeces[0]).zIndex() + 1;
    }

}

//My grid is in a div with id jqxgrid. All of its child elements need
//to be considered when figuring out the next available ZIndex
var foo = new ZIndexer().Add(&quot;#jqxgrid *&quot;);

//Set the z-index of the jquery-ui dialog and its overlay to the highest available
$('.ui-widget-overlay').css('z-index',foo.GetNextFreeZIndex());
$('.ui-dialog').css('z-index',foo.GetNextFreeZIndex() + 1);