NHibernate Eager Loading Retrieving Duplicate Results

by Michael Henstock 31. January 2014 08:29

Recently, I had created a query for an entity while attempting to eager load 2+ child lists using NHibernate. Eager loading a single child list was working correctly, however, when I started to attempt to eager load 2 or more child lists, all of the child lists would end up with A * B * C...* N number of records.

Using NHibernate Linq, the queries looked something like this:

var result =
    Session.Query<MyEntity>()
        .Where(x => x.Id == 1)
        .Fetch(x => x.ChildList1)
        .Fetch(x => x.ChildList2)
        .Single();

After digging around for a while, I found that I could get around this by using NHibernates .ToFuture() method as such:

Session.Query<MyEntity>()
    .Where(x => x.Id == 1)
    .Fetch(x => x.ChildList1)
    .ToFuture();

var result =
    Session.Query<MyEntity>()
        .Where(x => x.Id == 1)
        .Fetch(x => x.ChildList2)
        .ToFuture()
        .Single();

This is a nice simple feature to execute multiple queries while only going to the database once and the queries don't necessarily need to be about related data (just in my instance here they are).

However, we're starting to duplicate logic from the query point of view. We're creating multiple IQueryable<MyEntity> items and filtering both on the identifier. If we take the IQueryable to a variable and create the futures from that, we can save whatever complex logic we may have built up to filter our data such as this:

var query = Session.Query<MyEntity>().Where(x => x.Id == 1);

query.Fetch(x => x.ChildList1).ToFuture();

var result =
    query
        .Fetch(x => x.ChildList2)
        .ToFuture()
        .Single();

Tags:

C# | NHibernate

Editing percentage values with a KendoUI NumericTextBox

by Michael Henstock 16. April 2013 23:48

KendoUI has some great widgets and functionality built into it, and while it's not the best library in every situation it's great in most situations. The numeric text box widget is a simple widget that I'm using more frequently for percentages, which is great, however our users are wanting something that the default functionality doesn't supply. Our users love the widget but want to edit the text with the whole numbers (5 for 5% instead of 0.05).

We achieved this by extending the MVVM functionality to include a new formatter in the KendoUI binders. The default binder looks something like this:

<input data-role="numerictextbox" data-format="p" data-bind="value: percent" />

Which shows the value as a whole percentage, and edits in the decimal place number.

By extending the KendoUI binders with the following:

kendo.data.binders.widget.percentage = kendo.data.Binder.extend({
    init: function (element, bindings, options) {
        kendo.data.Binder.fn.init.call(this, element, bindings, options);

        var that = this;
        that.element.options.format = "#.00 \\%";
        that.element.options.min = that.element.options.min || 0;
        that.element.options.max = that.element.options.max || 100;

        that.element.element.on("change", function () {
            that.change();
        });
    },
    refresh: function () {
        var that = this,
            value = that.bindings["percentage"].get();

        // Take a percentage value and display it in a simpler percentage format
        that.element.value(value * 100);
    },
    change: function () {
        var value = this.element.value();
        if (!isNaN(value)) {
            // divide the percentage value by 100 to set the model value to the database percentage value
            this.bindings["percentage"].set(value / 100);
        }
    }
});

we can change our input binding to this:

<input data-role="numerictextbox" data-bind="percentage: percent" />

and get the same functionality and the ability to edit the percentages as whole numbers.

You can see a demonstration of this here: http://jsbin.com/ekovif/1/edit

Tags:

JavaScript | KendoUI

Custom JavaScript handler to process the last event occurring instead of every event

by Michael Henstock 7. April 2013 10:02

I recently had a requirement to bind to a browser resize event that would adjust an elements size. Now that's all well and fine except you can get hundreds of resize events firing during the user resizing the browser. What we really want is to apply the changes after the user has finished resizing the window.

Now, there are plenty of third party libraries that provide this capability and a lot more (the Reactive Extensions library by Microsoft is the first that comes to my mind [http://msdn.microsoft.com/en-us/data/gg577609.aspx]), but my requirements were very simple and didn't need a full library. All our requirements are for an event to be called back half a second after the resize events have stopped calling.

var __customEventsHandler;
(function (events) {
    var timers = { };
    events.waitForFinalEvent = function(callback, ms, uniqueId) {
        if(!uniqueId) {
            throw "must specify uniqueId";
        }
        if(timers[uniqueId]) {
            clearTimeout(timers[uniqueId]);
        }
        timers[uniqueId] = setTimeout(callback, ms);
    }
})(__customEventsHandler || (__customEventsHandler = {}));

This gives us a __customEventsHandler.waitForFinalEvent function that takes the callback to run when the events stop occurring, the expected timeout milliseconds to wait and an uniqueId that we specify for the bind event to allow the handler to contain whatever timeout identifiers it needs to cancel/complete the timeouts.

How we can call this is via the following code:

$(window).resize(function () {
    __customEventsHandler.waitForFinalEvent(function () {
        alert('resize complete!')
    }, 500, "my_window_resize");
});

With the alert appearing 500 milliseconds after no more resize events have occurred.

Tags:

JavaScript

Wrapping an existing classes properties with nullable values

by Michael Henstock 30. January 2013 11:57

One of the things that I have needed to do recently was to take an existing class definition, clone it and turn all the value type properties into nullable definitions. We were doing this on some POCO with data obtained from our database, and needed to have a separate override object that we could default to the POCO data when null.

We created a generic class that would act as our wrapper with Set and Get methods to access the properties, with an expression parameter to strongly type the property name. I just used a simple dictionary as storage for the property values.
 
public class OverrideWrapper<TEntity>
{
    private Dictionary<string, object> _propertyStore = new Dictionary<string, object>();

    public Nullable<TValue> GetProperty<TValue>(Expression<Func<TEntity, TValue>> getter) where TValue : struct
    {
        return GetPropertyHelper<Nullable<TValue>, TValue>(getter);
    }

    public string GetProperty(Expression<Func<TEntity, string>> getter)
    {
        return GetPropertyHelper<string, string>(getter);
    }

    private TResult GetPropertyHelper<TResult, TValue>(Expression<Func<TEntity, TValue>> getter)
    {
        if (getter == null)
            throw new ArgumentNullException("getter");

        var propertyName = GetPropertyNameFromExpression(getter);

        return (TResult)GetProperty(propertyName);
    }

    private string GetPropertyNameFromExpression<TValue>(Expression<Func<TEntity, TValue>> exp)
    {
        var expression = (MemberExpression)exp.Body;

        // If we're accessing the Value property of a Nullable object, return the name of the Nullable property, not the Value property.
        if (expression.Expression != null &&
            expression.Expression is MemberExpression &&
            ((MemberExpression)expression.Expression).Type.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            return ((MemberExpression)expression.Expression).Member.Name;
        }
        else
        {
            return expression.Member.Name;
        }
    }

    public object GetProperty(string propertyName)
    {
        if (propertyName == null)
            throw new ArgumentNullException("propertyName");

        if (_propertyStore.ContainsKey(propertyName) && _propertyStore[propertyName] != null)
            return _propertyStore[propertyName];

        return null;
    }

    public void SetProperty<TValue>(Expression<Func<TEntity, TValue>> setter, TValue value) where TValue : struct
    {
        SetPropertyHelper(setter, value);
    }

    public void SetProperty(Expression<Func<TEntity, string>> setter, string value)
    {
        SetPropertyHelper(setter, value);
    }

    private void SetPropertyHelper<TValue>(Expression<Func<TEntity, TValue>> setter, TValue value)
    {
        if (setter == null)
            throw new ArgumentNullException("setter");

        var propertyName = GetPropertyNameFromExpression(setter);

        _propertyStore[propertyName] = value;
    }
}
We limited the properties to structs and strings hence the need for two overloaded methods, one for the generic structs and the other for the string properties.
 
A simple example of usage follows:
public class SampleObject
{
    public string StringProp { get; set; }
    public int IntProp { get; set; }
    public decimal DecimalProp { get; set; }
}

var test = new OverrideWapper<SampleObject>();

test.GetProperty(p => p.IntProp); // == null
test.GetProperty(p => p.StringProp); // == null

test.SetProperty(p => p.IntProp, 10);
test.SetProperty(p => p.StringProp, "set value");

test.GetProperty(p => p.IntProp); // == 10
test.GetProperty(p => p.StringProp); // == "set value"

Tags:

C#

Passing information to and from different plugins in CruiseControl.net

by Michael Henstock 8. January 2013 11:56

Passing a value from a custom trigger plugin to another plugin inside CruiseControl.net is quite simple.

From the ITrigger.Fire() method, CruiseControl.net expects an IntegrationRequest to be returned. In this object we can add the information that we wish to pass to our next plugin. To do this, we add our information to the BuildValues Dictionary<string, string> like this:
var request = new IntegrationRequest(buildCondition, "New integration request", null);
request.BuildValues.Add("my_info", "test info");
When a build is successfully started in CruiseControl.net, these values are parsed into the Parameters NameValuePair list on the IIntegrationResult object, that is either passed to your objects through the standard interface. This can be accessed like this:
var labelParameter = integrationResult.Parameters.SingleOrDefault(x => x.Name == "my_info");
if (labelParameter != null)
    return labelParameter.Value;

Tags:

C# | CruiseControl.net

Using Sql Server 2008 DataTable parameters with NHibernate

by Michael Henstock 8. December 2012 11:47

Hitting the maximum parameter limit of 2100 for an Sql Server query generally points to deeper issues in the design of your application and should be a sign for the need of refactoring than anything else. However, there are some rare cases where this really is the best solution and you need to get around this limit.

With Sql Server 2008+ we can use table valued parameters to a query (http://msdn.microsoft.com/en-us/library/bb510489.aspx) when we need to pass in a large set of parameter queries. While great for direct queries, this feature isn't supported in NHibernate due to the specifics around actually implementing such a feature make it nigh impossible to do so without breaking the generic wrapper interface around all of the databases that NHibernate supports.

NOTE: While the following does allow usage of table valued parameters with NHibernate, it is a hack that works around and with NHibernates plugin infrastructure. While NHibernate is beautifully extensible, I wasn't able to find a way to implement this without the hacks as described in the following. If anyone knows of a better way to implement this, I would love to know.
 
So to begin, we need to create a table type within the target database:
CREATE TYPE [dbo].[IdentifierTable] AS TABLE([ID] [uniqueidentifier] NULL);
Here we create a table type with a field that is of the same data type as the fields we wish to query in volume. Next, we create an
extension method working off the data type that we want to query (in this case a Guid):
public static bool IsIn(this Guid source, IEnumerable<Guid> idList)
{
     throw new NotImplementedException();
}
This gives us a method to call in our NHibernate Linq query to use when we want to override the default NHibernate behaviour to use the
table type parameters. Next we need a generator class which generate the HQL used by NHibernate for this query.
There's no method (that I know of) that allows us to call the table type parameter with a DataTable within HQL. As such, we're just putting
the default code that NHibernate generates for a standard Contains HQL filter and adding a wrapper around this (the hacks begin!):
 
public class IsInDataTableGenerator : BaseHqlGeneratorForMethod
{
    public const string DATA_TABLE_PARAMETER_VALUE = "DATA_TABLE_PARAMETER_VALUE";
    public IsInDataTableGenerator()
    {
        SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition(() => MyNHibernateExensions.IsIn(Guid.Empty, null)) };
    }

    public override HqlTreeNode BuildHql(
        MethodInfo method,
        Expression targetObject,
        ReadOnlyCollection<Expression> arguments,
        HqlTreeBuilder treeBuilder,
        IHqlExpressionVisitor visitor)
    {
        return
            treeBuilder.BooleanAnd(
                treeBuilder.BooleanAnd(
                    treeBuilder.Equality(treeBuilder.Constant(DATA_TABLE_PARAMETER_VALUE), treeBuilder.Constant(DATA_TABLE_PARAMETER_VALUE)),
                    treeBuilder.In(
                        visitor.Visit(arguments[0]).AsExpression(),
                        visitor.Visit(arguments[1]).AsExpression())),
                treeBuilder.Equality(treeBuilder.Constant(DATA_TABLE_PARAMETER_VALUE), treeBuilder.Constant(DATA_TABLE_PARAMETER_VALUE)))
            ;
    }
}
This adds in the standard HQL for value IN (value list) queries, and wraps the start and end with 'DATA_TABLE_PARAMETER_VALUE' = 'DATA_TABLE_PARAMETER_VALUE' filters. Next we need to register the extension method with NHibernate:
class LinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
     public LinqToHqlGeneratorsRegistry()
     {
         RegisterGenerator(
             ReflectionHelper.GetMethodDefinition(() => MyNHibernateExensions.IsIn(Guid.Empty, null)),
             new IsInDataTableGenerator());
     }
}
This simply registers the extension with NHibernate and lets it know to use the IsInDataTableGenerator for the Linq queries that use that
function. Next up, we need to really get our hacks in full motion. We create a new class that inherits from the default NHibernate
Sql2008ClientDriver and override the OnBeforePrepare method. This takes in the final IDbCommand object that will be sent to the database,
so we start by inspecting the actual Sql and play around with that to inject our Sql to filter against the table type.
class MySql2008ClientDriver : Sql2008ClientDriver
{
    private static readonly Regex SubstitutionRegEx =
        new Regex(
            "'" + IsInDataTableGenerator.DATA_TABLE_PARAMETER_VALUE + "'='" + IsInDataTableGenerator.DATA_TABLE_PARAMETER_VALUE + 
            "'.+?'" + IsInDataTableGenerator.DATA_TABLE_PARAMETER_VALUE + "'='" + IsInDataTableGenerator.DATA_TABLE_PARAMETER_VALUE + "'",
            RegexOptions.Compiled);
    private static readonly Regex ParameterMapRegEx = new Regex(@"(\@p.*?)\b\)", RegexOptions.Compiled);
    private static readonly Regex FieldRegEx = new Regex(@"\(.*?\(", RegexOptions.Compiled);

    protected override void OnBeforePrepare(IDbCommand command)
    {
        foreach (var substitution in SubstitutionRegEx.Matches(command.CommandText).Cast<Match>().Select(x => x.Value))
        {
            // Grab a string array of parameter names being passed into the filter
            var parameters = ParameterMapRegEx.Match(substitution).Value.Replace(')', ' ').Replace(" ", "").Split(',');
            // prepare the replacement filter statement
            var filterStatement = FieldRegEx.Match(substitution).Value + "SELECT ID FROM " + parameters[0] + "))";

            // Add the list of parameter values into a DataTable and remove them from the command.
            var table = new DataTable();
            table.Columns.Add(new DataColumn("ID", typeof(Guid)));
            foreach (var sqlParameter in parameters.Select(parameter => ((SqlParameter)command.Parameters[parameter])))
            {
                table.Rows.Add(sqlParameter.Value);
                command.Parameters.Remove(sqlParameter);
            }

            // Add the substitute parameter with the datatable value
            command.Parameters.Add(
                new SqlParameter
                {
                    SqlDbType = SqlDbType.Structured,
                    TypeName = "IdentifierTable",
                    Value = table,
                    ParameterName = parameters[0]
                });
            // replace the substitution string with the replacement filter
            command.CommandText = command.CommandText.Replace(substitution, filterStatement);
        }
    }
}
This uses regular expressions to grab out all the where conditions with the "DATA_TABLE_PARAMETER_VALUE" wrapper. Then gets the field name it's filtering on plus all the Sql parameters being passed into the command for that filter statement. Then builds up a DataTable object with the same structure as the table type, inserts rows with all the values in the sql parameters, and removes the parameters from the query. Then finally adds in a new parameter with the TypeName pointing to the table type, and the DataTable created as the value. Finally we replace the old Sql IN filter with a new one that only checks the field IN the newly added table type parameter.
 
Lastly, we just need to update the NHibernate configuration to use the override classes show above. When we configure your NHibernate SessionFactory, we need to add the following:
config.Properties["connection.driver_class"] = typeof (MySql2008ClientDriver).AssemblyQualifiedName;
config.LinqToHqlGeneratorsRegistry<LinqToHqlGeneratorsRegistry>();
The first line simply overrides the default client driver class with our overridden class. The second just adds our Linq to HQL registration class to the list of registry classes.
 
Once this has all been done, our queries simply become a case of calling the Linq extension method in our NHibernate IQueryables like the following:
var filterIds = new Guid[3000];
// Populate filterIds with values
session.Query<MyTest>().Where(r => r.id.IsIn(filterIds));

Tags:

C# | NHibernate

Using a "data builder" class for isolating database data in individual tests

by Michael Henstock 23. November 2012 11:40

This post is mostly a reply to this (http://lostechies.com/jimmybogard/2012/10/18/isolating-database-data-in-integration-tests/) post by Jimmy Bogard.

 
How my company has managed the test databases for integration tests is through a class library to handle inserting, updating and cleaning up of the database for an integration test. This class library has a whole bunch of helper methods which simplifies creating data by defaulting the majority of values on each entity and basic management of table relations. Rather than creating deleting and re-creating the entire database, or tables within the database or running all integration tests within a transaction then rolling back, we use our data builder to put data into the database and at the end of the test it knows what was added and just deletes the added items from each table.
 
The goal of using this class library is to have a test class that looks something like this:
[TestFixture]
public class TestClass
{
    SqlDatabuilder _builder;

    [SetUp]
    public void SetUp()
    {
        _builder = new SqlDatabuilder();
        _builder
            .AddTestRow(1, x => x.field2 = "field 2")
            .AddTest2Row(2, x => x.field2 = "field 2")
            .AddTest2Row(3, x => x.field2 = "field 2")
            ;
    }

    [TearDown]
    public void CleanUp()
    {
        _builder.CleanUp();
    }

    [Test]
    public void TestX()
    {
        // Add assertions working on TestRow class.
    }
}
The intention of the SqlDataBuilder class is to simplify adding data to whatever back end service we're using, while keeping a stack of changes that the data builder creates, then roll those changes back in reverse order when we need to do a clean up. That way the creation of custom data setup for a specific test is easy and the clean up of this data is completely handled by the cleanup step.
 
The main area where things can start to unravel is when the test itself is adding data that the data builder isn't aware of, which can cause foreign key exceptions in the clean up step. How we handle these situations is to have another helper method on the data builder that allows us to add some custom clean up actions that the clean up method calls before the standard clean up roll back occurs. This looks something like this:
[TearDown]
public void CleanUp()
{
    _builder
        .AddCleanUpSql("DELETE FROM test3")
        .CleanUp();
}
The majority of the code is handled in the BaseDataBuilder class which I've attached below. A sample implementation which handles the connection to the database and the wrapper methods for adding data to specific tables is shown here with comments:
// The BaseDataBuilder class implements a lot of the plumbing around inserting, updating and deleting data.
// This class is for calling the generic methods with specific helper methods that default all the data.
public class SqlDatabuilder : FluentDataBuilder.BaseDatabuilder
{
    private System.Data.IDbConnection _dbConnection;
    protected override System.Data.IDbConnection dbConnection
    {
        get
        {
            return _dbConnection jQuery152036569983838126063_1365248451800
                (_dbConnection = new System.Data.SqlClient.SqlConnection("Data Source=localhost;Integrated Security=SSPI;database=test;"));
        }
        set
        {
            _dbConnection = value;
        }
    }

    public SqlDatabuilder AddCleanUpSql(
        string sql)
    {
        this.AddDeleteSql(sql);

        return this;
    }

    // The DataContainer class contains the local copy of the databuilders data that has been created
    // This property is implementing the container for a specific table in this case, the table behind TestRow
    private FluentDataBuilder.DataContainer<TestRow, int> _testRowContainer;
    public FluentDataBuilder.DataContainer<TestRow, int> TestRowContainer
    {
        get
        {
            return _testRowContainer jQuery15201317599972244352_1365248810643
                (_testRowContainer = new FluentDataBuilder.DataContainer<TestRow, int>(this, "TestRow"));
        }
    }

    private FluentDataBuilder.DataContainer<TestRow, int> _testRow2Container;
    public FluentDataBuilder.DataContainer<TestRow, int> TestRow2Container
    {
        get
        {
            return _testRow2Container jQuery15201766282683238387_1365330478024
                (_testRow2Container = new FluentDataBuilder.DataContainer<TestRow, int>(this, "TestRow2"));
        }
    }

    // A helper method which adds a new TestRow to the TestRowContainer, defaults the field1 property with the
    // identifier parameter, then calls the InsertEntity helper method which inserts the value straight into the database.
    public SqlDatabuilder AddTestRow(int identifier, Action<TestRow> setProperties = null)
    {
        TestRowContainer.Add(
            identifier,
            x => 
                {
                    x.field1 = identifier;

                    if (setProperties != null)
                    {
                        setProperties(x);
                    }
                },
            x => InsertEntity("test", x, t => t.field1));

        return this;
    }

    // Another helper method similar to the AddTestRow, except it ensures that TestRowContainer has a current value
    // Then adds an item to the TestRow2Container, with information from the TestRowContainer.Current item.
    public SqlDatabuilder AddTest2Row(int indentifier, Action<TestRow> setProperties = null)
    {
        TestRowContainer.EnsureCurrentSet();

        TestRow2Container.Add(
            indentifier,
            x =>
            {
                x.field1 = indentifier;
                x.field2 = TestRowContainer.Current.field1.ToString();

                if (setProperties != null)
                {
                    setProperties(x);
                }
            },
            x => InsertEntity("test", x, t => t.field1));

        return this;
    }
}
The great thing about having the FluentDataBuilder.DataContainer implementation allows the tests to get the most recently added entity (via the Current property) for identifiers or any other settings, and a dictionary based off a key which gives the tests quick access to any of the prepared test data.

 

FluentDataBuilder.zip (3.87 kb)

Tags:

C# | Unit Tests

Using the Bundling and Minification Web Optimisations with Asp.Net WebForms App_Themes

by Michael Henstock 30. October 2012 11:17

The bundling and minification that arrived with the latest .Net 4.5 framework is a great tool. For those web applications that are using the WebForms App_Themes folder to style an application, it won't quite work as well as it is capable of. The App_Themes folder will automatically render down all CSS files it finds in the folder and sub directories, so if you register these files in your bundle config you will end up with two versions of the stylesheet rendered down to the client.

So how do we dynamically register some CSS files in an App_Theme folder without the default files being rendered down to the client? The short answer is, you can't. The long answer is, we can with a bit of a work around.

If we take out the CSS files (including any images etc referenced by the style sheets) and move them to another folder, say AppTheme, put our files into a directory under the AppTheme folder with the same theme name, let's go with Default. We can now go and register these files in our bundle config. The default method for registering style sheets isn't quite going to cut it as that defines all the file locations at application load time and we're going to want to dynamically change this folder depending on the theme selected for the current request.
 
Luckily, we already have this capability in the default web optimisation library. We just need to use the DynamicFolderBundle class as follows:
bundles.Add(new DynamicFolderBundle("Style", "*.css"));
And then on the page where you register the bundle, you can just register it with the following:
<%: System.Web.Optimization.Styles.Render("~/AppThemes/" + this.Theme + "/Style") %>
Which tells the bundler to look under the AppThemes/{ThemeName} folder and register all the css files under the one bundle. It's also possible for the DynamicFolderBundle to search all the sub-directories for CSS files, but you'll want to be careful with that if you have styles that reference external files such as background images.

Tags:

Asp.Net | C#

Extending CruiseControl.net with a sample trigger that fires when a file exists

by Michael Henstock 21. October 2012 11:03

This is a simple example of a CruiseControl.net Trigger server plugin which is based on the sample given in the source code. It's probably best to familiarise yourself with that and the plugin examples at http://www.cruisecontrolnet.org/projects/ccnet (of which this example is heavily based off, if you really wanted you could just go and play with the sample code provided by cruisecontrol.net and skip this article, it's okay I won't be offended).

The first caught me out (despite it being well documented here), was the need to name your plugin dlls in the format of ccnet.*.plugin.dll. That's the only requirement for your plugins as once cruise control has that it just uses reflection to find everything it needs from your dll.

To start, create your class, have it implement the ITrigger interface, and assign the ReflectorType attribute to the class with the name of your trigger as a parameter. This name is the name that will be used in the XML project configuration and can be completely different from the class name if you wish.

[ReflectorType("mySampleTrigger")]
public class SampleTrigger : ITrigger
{
    #region ITrigger Members

    public IntegrationRequest Fire()
    {
        throw new NotImplementedException();
    }

    public void IntegrationCompleted()
    {
        throw new NotImplementedException();
    }

    public DateTime NextBuild
    {
        get { throw new NotImplementedException(); }
    }

    #endregion
}

The Fire() method is the method that is called every time that CruiseControl has scheduled the next integration to occur. If you have this scheduled to occur once every minute, it will call the Fire() method every minute. This is where you want to declare your logic to determine if a build should occur.

The IntegrationCompleted() method is logic that will be called after a build has finished running that has this trigger.

The NextBuild property is used by CruiseControl to determine when the next call to the Fire method of the trigger should occur.

Now that we understand the basics of the interface, lets look at how we can create a simple trigger that fires every 15 seconds.

To start, we need access to the CruiseControl.net DateTimeProvider class. To do this, lets create a constructor to accept the provider and assign it to a field.

DateTimeProvider _dateTimeProvider;

public SampleTrigger()
    : this(new DateTimeProvider())
{
}

public SampleTrigger(DateTimeProvider dateTimeProvider)
{
    _dateTimeProvider = dateTimeProvider;
}

Next, we'll implement the NextBuild property in the interface:

public DateTime NextBuild { get; private set; }

and assign Now + 15 seconds to it in the constructor of the class:

public SampleTrigger(DateTimeProvider dtProvider)
{
    _dateTimeProvider = dtProvider;
    NextBuild = _dateTimeProvider.Now.AddSeconds(15);
}

Now we need to implement the Fire method. We just need to check the current time against the most recent time stored in the NextBuild property. If it is less than the 15 seconds stated above, we just return null, otherwise we return a new IntegrationRequest object to tell CruiseControl that we want a build to occur.

public IntegrationRequest Fire()
{
    if (_dateTimeProvider.Now < NextBuild)
        return null;

    return new IntegrationRequest(BuildCondition.ForceBuild, "Sample Trigger says GO!", null);
}

The BuildCondition parameter in the IntegrationRequest constructor can give CruiseControl a bit more information, such as only causing a build if there are modifications found within source control. As we want a build to occur every 15 seconds no matter what, we're just going to return a ForceBuild.

Finally, we'll implement the integration request to handle any post build processing, in this case, we'll just increment the NextBuild so that the next one will occur 15 seconds after the end of the current build.

public void IntegrationCompleted()
{
    NextBuild = _dateTimeProvider.Now.AddSeconds(15);
}

So finally our trigger should look something like this:

[ReflectorType("uiTestTrigger")]
public class SampleTrigger : ITrigger
{
    DateTimeProvider _dateTimeProvider;

    public SampleTrigger()
        : this(new DateTimeProvider())
    {
    }

    public SampleTrigger(DateTimeProvider dtProvider)
    {
        _dateTimeProvider = dtProvider;
        NextBuild = _dateTimeProvider.Now.AddSeconds(15);
    }

    #region ITrigger Members

    public IntegrationRequest Fire()
    {
        if (_dateTimeProvider.Now < NextBuild)
            return null;

        return new IntegrationRequest(BuildCondition.ForceBuild, "Sample Trigger says GO!", null);
    }

    public void IntegrationCompleted()
    {
        NextBuild = _dateTimeProvider.Now.AddSeconds(15);
    }

    public DateTime NextBuild { get; private set; }

    #endregion
}

Now, having a build occur every 15 seconds isn't really useful (and the interval trigger already does that for us if that's what you need). However, if we wanted to extend this to say, fire a build when a file exists on disk, it's a simple process of just adding that to this class with a few lines of code.

So to start, we alter the Fire method to check if a file exists:

public IntegrationRequest Fire()
{
    if (_dateTimeProvider.Now < NextBuild)
        return null;

    NextBuild = _dateTimeProvider.Now.AddSeconds(15);

    if (!File.Exists(@"C:\Temp\test.txt"))
        return null;

    return new IntegrationRequest(BuildCondition.ForceBuild, "Sample Trigger says GO!", null);
}

The only other thing we have added here is to increment the NextBuild property 15 seconds after we have passed the existing 15 second counter to force this file check to only occur every 15 seconds. And that's it, we're now checking if a file exists every 15 seconds, and if it does we're telling CruiseControl to force a build to start.

Where to from here? You can then start extending this such that the 15 second increment value and the file on disk are properties of the trigger that can be configured in the build configuration file to truly extend this trigger.

Tags:

C# | CruiseControl.net

The Power of Expression Trees with ORMs such as NHibernate and Entity Framework

by Michael Henstock 20. August 2012 10:35
Lets start with a quick, simple example. Lets start with a simple Entity:
public class SimpleEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

List<SimpleEntity>()
    {
        new SimpleEntity() { Id = 1, Name = "Entity 1" },
        new SimpleEntity() { Id = 2, Name = "Entity 2" },
        new SimpleEntity() { Id = 3, Name = "Entity 3" }
    };
entites.Where(e => e.Id == 2);
Which would return an IEnumerable<SimpleEntity> with the second item added in the list.
 
Now, say we didn't know the field we wanted to query on, how could we go about that? Firstly, we need become great friends with System.Linq.Expressions.Expression. This is the base class for all parts of an expression tree which builds up a LINQ query. Let's dive into doing the above query the analyse its parts.
var parameter = Expression.Parameter(typeof(SimpleEntity), "e");
entities.Where(
    Expression.Lambda<Func<SimpleEntity, bool>>(
        Expression.Equal(
            Expression.Property(parameter, "Id"),
            Expression.Constant(2)),
        parameter)
        .Compile());
So, first up we're creating a parameter named "e" that is defined as a type of SimpleEntity. Pretty straight forward, and in the simple LINQ query above this is the e =>
 
Next we have Expression.Lambda<Func<SimpleEntity, bool>> which is us telling the runtime that we're going to build up an expression tree which looks like a function that takes a SimpleEntity as a parameter and returns a bool result.
 
Then we are building up a BinaryExpression where we are doing an equality check for the property Id on parameter "e" and comparing that to the constant value of 2.
 
Then we pass in the parameter to the lambda as well to pass the property "e" up the hierarchy of the expression tree to the area it is used.
 
Finally, as the List Where method requires a Func<SimpleEntity, bool> parameter, rather than the Expression object tree we have built up, we call the Compile() which returns a delegate of the type specified which is then called in the Where method and the returns the single entity. Building up an expression tree and compiling at run time is not very efficient, so you need to look into where and when you would use something like this to build up a delegate and make sure you're not over-engineering something that could be done simpler.
 
The real power of expression trees comes about when we start to look at IQueryable and how ORMs interpret these IQueryable LINQ entities. NHibernate, Entity Framework and their ilk use IQueryable definitions to define SQL queries in Expression tree code form, as per this example:
NHibernate.ISession sessionObject;
var query = sessionObject.Query<SimpleEntity>();
query.Where(e => e.Id == 2);
This would be interpreted by NHibernate when the query is complete and being executed into SQL something like this:
SELECT * FROM SimpleEntity WHERE Id = 2
Now we can take a IQueryable object, build it up with a few via both lambda expressions and expression trees, have NHibernate interpret that into SQL and execute your dynamic expression tree as SQL against your database. This could look something like this:
var query = sessionObject.Query<SimpleEntity>(); 
query = query.Where(e => e.Id == 2);
query = query.Where(
    Expression.Lambda<Func<SimpleEntity, bool>>(
        Expression.Equal(
            Expression.Property(parameter, "Name"),
            Expression.Constant("Entity 2")),
        parameter));
And this would come out like:
SELECT * FROM SimpleEntity WHERE Id = 2 AND Name = 'Entity 2'
This isn't just for filtering either, you can order results, select results, group results etc, all using the power of Expression trees. While these examples are really very basic, it very quickly expands out into powerful (and complicated!) expressions.
 
A final example without much explanation, this is looping through a list of names, and depending on custom markers in the name, filtering a query on each Persons name and these are OR'd to find all the Person entities in the supplied names enumerable:
Expression<Func<Person, bool>> expr = null;
foreach (var name in names)
{
    if (!string.IsNullOrEmpty(name))
    {
        var searchName = name.Replace("%", "");
        Expression<Func<Person, bool>> newPred;
        if (name.EndsWith("%") && !name.StartsWith("%"))
        {
            newPred = i => i.name.StartsWith(searchName);
        }
        else if (name.StartsWith("%") && !name.EndsWith("%"))
        {
            newPred = i => i.name.EndsWith(searchName);
        }
        else
        {
            newPred = i => i.name == searchName;
        }
        expr = expr == null
            ? newPred
            : Expression.Lambda<Func<InvestorView, bool>>(
                  Expression.OrElse(
                      expr.Body,
                      Expression.Invoke(
                          newPred,
                          expr.Parameters.Cast<Expression>())),
                      expr.Parameters);
    }
}
query.Where(expr);

Tags:

C# | NHibernate