Home » Blog

rounded header

What’s new in NHibernate Designer 2.1?

We’re pleased to announce the release of NHibernate Designer 2.1, an update to our popular visual design and mapping tool for the well-known open-source object-relational mapper.

Version 2.1 rolls up a number of fixes that we’ve made over the last six months, and includes some great new features as well:

  • Table per subclass inheritance
  • One-way associations
  • Drag views and stored procedures onto the designer
  • Mark up the generated entities with WCF data contract attributes
  • More control over property visibility
  • Support for the sql-insert, sql-update and sql-delete overrides
  • Formula properties
  • Support for named SQL queries
  • Composite foreign keys
  • Improved support for creating through tables for many-to-many associations
  • Support for the hated, but sometimes necessary, foreign identity generator

The NHibernate Designer is FREE for up to 10 entity classes and you can upgrade to the unlimited edition for just $99. Or act quick and get it as part of our MegaPack Sale — 50% off until the end of April!

To install or update the NHibernate Designer go into Visual Studio Extension Manager, choose the Online Gallery tab and search for “Mindscape NHibernate Designer.” Or download it here!



Nightly news, 27 April 2012

WPF Elements

  • Charting performance improvements
  • The Chart control now provides a FinishedPlotting event
  • Fixed a bug with displaying lots of data in a stacked chart
  • Added support for customising the scheduler recurrence dialogs
  • ScheduleFormatter now provides an option for customising the default name of newly created schedule items
  • Fixed a bug in the TimePicker control
  • You can now customise the background of individual cells, rows and columns of a DataGrid
  • The DataGrid no longer performs highlighting on mouse-over in RowAndCell mode, except when the mouse is over the row header
  • Added validation support to DataGrid DisplayMemberBinding
  • If you set the Value directly on a numeric text box, it now constrains the value to the permitted range instead of throwing an exception

LightSpeed

  • Fix for error during database update if a design-time assembly could not be found
  • Fix for error in SaveChanges under heavy load
  • Improvements to grouping support: better support for functions and traversals in grouping keys
  • Change to allow non-nullable GUID, DateTime and blob columns to be added to existing SQLite tables

Web Workbench

  • Added an option to show generated files when choosing files to merge during minification

NHibernate Designer

  • Added support for table per subclass inheritance
  • Added support for creating MySQL MEDIUMTEXT and LONGTEXT columns

All these features and fixes are in the current nightly builds — free editions from the Downloads page, full editions from the store.



Customizing the WPF scheduler dialog boxes

tag icon Tagged as WPF Elements

One of the controls in our WPF Elements control suite is the familiar Outlook styled Scheduler. This lets users add, edit and view appointments that are scheduled to occur at a particular date and time. Some of these actions such as editing a recurrence pattern are performed by the user changing values in a dialog box as seen below.

Recurrence Dialog

In the current nightly build we have made it easier to customize the template of these dialog boxes. By customizing the dialog boxes you can change the colors and styles of the various controls to suit the needs of you application. This also means you can localize the dialogs by changing the text labels. The best way to create a custom dialog style is to start with the code for the default style and then alter it however you need. Below is the default styling code for the dialog used for adding schedule items.

<ms:BooleanToObjectConverter x:Key="RecurrenceButtonContentConverter" TrueObject="Edit Recurrence" FalseObject="Add Recurrence" />
 
<Style x:Key="ScheduleItemDialogStyle" TargetType="ms:ScheduleItemDialog">
    <Setter Property="Title" Value="New Appointment" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid x:Name="LayoutRoot" Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="70" />
                        <ColumnDefinition Width="10" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="22" />
                        <RowDefinition Height="10" />
                        <RowDefinition Height="22" />
                        <RowDefinition Height="10" />
                        <RowDefinition Height="22" />
                        <RowDefinition Height="10" />
                        <RowDefinition Height="22" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
 
                    <Button Command="{x:Static ms:SchedulerCommands.EditRecurrenceCommand}" Grid.Column="2" Width="100" HorizontalAlignment="Left"
                            Content="{Binding HasRecurrence, Converter={StaticResource RecurrenceButtonContentConverter}, RelativeSource={RelativeSource TemplatedParent}}" />
 
                    <TextBlock TextAlignment="Right" VerticalAlignment="Center" Grid.Row="2">Subject:</TextBlock>
                    <TextBox Text="{Binding Subject, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="2" />
 
                    <TextBlock TextAlignment="Right" VerticalAlignment="Center" Grid.Row="4">Start time:</TextBlock>
                    <StackPanel Orientation="Horizontal" Grid.Row="4" Grid.Column="2">
                        <ms:DropDownDatePicker Width="205" Margin="0,0,10,0" Value="{Binding StartDate}" Format="Custom" CustomFormat="dd/MM/yyyy" />
                        <ms:TimePicker Width="80" SelectedTime="{Binding StartTime}" ItemsSource="{Binding StartTimeList}" />
                    </StackPanel>
 
                    <TextBlock TextAlignment="Right" VerticalAlignment="Center" Grid.Row="6">End time:</TextBlock>
                    <StackPanel Orientation="Horizontal" Grid.Row="6" Grid.Column="2">
                        <ms:DropDownDatePicker Width="205" Margin="0,0,10,0" Value="{Binding EndDate}" Format="Custom" CustomFormat="dd/MM/yyyy" />
                        <ms:TimePicker Width="80" SelectedTime="{Binding EndTime}" ItemsSource="{Binding EndTimeList}" />
                    </StackPanel>
 
                    <StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="2">
                        <Button Command="{x:Static ms:SchedulerCommands.OkCommand}" Content="Save &amp; Close" Width="95" Height="23" Margin="0,18,0,0" />
                        <Button Command="{x:Static ms:SchedulerCommands.CancelCommand}" Content="Cancel" Width="75" Height="23" Margin="10,18,0,0" />
                    </StackPanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The default styling code for all 3 dialog box templates can be downloaded here. You may notice that each style is also setting the Title property using a setter. This changes the title of the dialog window which is convenient for localization or to simply provide a different title. In order for the Scheduler control to use your custom styles, you just need to create an instance of the SchedulerFormatter and set the appropriate properties. This is demonstrated in the code below.

<ms:SchedulerFormatter x:Key="Formatter"
                       ScheduleItemDialogStyle="{StaticResource ScheduleItemDialogStyle}"
                       RecurrenceDialogStyle="{StaticResource RecurrenceDialogStyle}"
                       DeleteRecurrenceDialogStyle="{StaticResource DeleteRecurrenceDialogStyle}"
                       DefaultScheduleItemName="New Schedule Item" />
 
<ms:Scheduler Formatter="{StaticResource Formatter}" />

Here I am also setting the DefaultScheduleItemName property which is also new in the latest nightly build. This lets you change the default name of newly created schedule items, which again is convenient for localization.

The current nightly build for the trial version can be downloaded from here, or you can go to your account page if you’re already a customer.

And that’s all you need to know to start creating your own custom dialog styles for the Scheduler. If you have any questions or need assistance with any of this, then we’d love to hear from you in the forum!



Nightly news, 20 April 2012

If there’s one thing the weekly updates are about, it’s beards, and it looks like that laser-like focus is finally paying off. But if there’s a second thing, I guess it would have to be keeping customers informed about what’s new and improved in the current nightly builds. Here’s what we’ve been busy on this week.

WPF Elements

  • Big charting performance improvements. We’ll have more to say about this in a future post. Ho yes.
  • Fixed a chart zooming bug when using non-primitive numeric types
  • Fix for bug in .NET 4.0 TextBox when used in a numeric DataGrid column
  • Fixed potential crash if axis properties were updated in an unexpected order
    Added a Tag property to DataGridColumn
  • Added a DisplayMemberBinding property to DataGridColumn. This simplifies creating complex bindings for a column without needing to create a custom template.

LightSpeed

  • You can now have multiple QueryFilterAttributes on a class, allowing you to build filters compositionally even in the absence of characterising interfaces.
  • Table names are no longer Pascalised if you have a design-time naming strategy and set UseClrNamingConventions to false
  • Added IOverrideClrConventions extension to IDesignTimeNamingStrategy to override default singularisation behaviour
  • Design-time assemblies with partial paths are now checked from the model directory as well as the current directory. This facilitates deployment of design-time assemblies via source control as part of the project.
  • Fix for error when performing a cast in LINQ Sum() or other aggregate operators but specifying the column in the Select()
  • Fixed projections into DateTime and nullable values when using query objects rather than LINQ

Web Workbench

  • Added option to default the “compile” setting to false
  • Added ‘stop on first error’ option for when a changed file has a lot of dependencies
  • Fixes for non-ANSI characters in Sass

Silverlight Elements

  • Added initial tab-indent support to HTML editor. Set CanHandleTabKey to enable this, and TabSize to customise the number of pixels that a tab indents by.

The latest nightlies are always available on the Downloads page (free editions) and in the Store (full editions).



Go with the dataflow

tag icon Tagged as General

Dataflow programming is a style that describes your data processing as data flowing through a graph of operations, in contrast to the usual imperative processing style. It invites you to think of data operations as a collection of black boxes, linked together by a runtime which takes care of moving data from one box to the next.

This may sound a little bit like LINQ, which makes it easy to compose set-based operations such as filtering and mapping without worrying about how the data gets from one operator to the next. You might even be reminded of the PowerShell pipeline, which pipes objects between composable commandlets. However, dataflow goes beyond a sequence of operations, allowing for flows to branch and join as required. Dataflow is also typically asynchronous, allowing for data to arrive and begin processing at arbitrary times — in this it’s more like the Reactive Extensions than LINQ.

In .NET 4.5, you can do dataflow programming using the new System.Threading.Tasks.Dataflow DLL. Here’s a quick look.

Dataflow ‘Hello, world’

If there’s one thing everybody hates more than a Fibonacci program, it’s a ‘Hello, world’ program, right? Well, tough. Here it comes.

// Set up the dataflow
var helloifier = new TransformBlock<string, string>(s => "Hello, " + s);
var printer = new ActionBlock<string>(s => Console.WriteLine(s));
helloifier.LinkTo(printer);
 
// Send some data into the dataflow
helloifier.Post("world");
 
Console.WriteLine("Prepare to be wowed");

This program sets up an almost trivial dataflow, consisting of just two blocks, a transform block and an action block. The transform block receives input, performs a transformation on it, and passes the result to its output. It’s the dataflow equivalent of the LINQ Select operator. In this case the transformation is to stick “Hello” on the front of the input. The action block receives input, does something with it, and doesn’t produce any output. In this case the thing it does is print it to the console. The program links the output of the transform block to the input of the action block.

Next, the program posts some data into the dataflow — specifically into the transform block, since that’s where our flow begins. Post is asynchronous, so it returns immediately, allowing the next statement to run. (You can also use SendAsync, which returns a Task object you can await on to know when the block consumed your input — this can be handy if you’re throwing a lot of data at a block.) Meanwhile the the dataflow kicks off in the background. First the transform block runs, producing the output “Hello, world”; then this output is passed via the link to the action block, which dumps this to the console. So the output is:

Prepare to be wowed
Hello, world

Notice that the Console.WriteLine in the main program ran before the one in the action block.

Dataflow is parallel

Obviously, dataflow isn’t terribly exciting for one message with trivial processing. Things start to hot up though when you have multiple data items or heavier processing needs. In this case dataflow will automatically parallelise the processing. You can control this using the ExecutionDataflowBlockOptions.MaxDegreeOfParallelism setting. In this example, I simulate CPU-bound operations in my transform and action blocks:

static void Busy() {
  for (int i = 0; i < 1000000000; ++i) { }
}
 
var bustagut = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 };
 
var helloifier = new TransformBlock<string, string>(
  s => { Busy(); return "Hello, " + s; },
  bustagut);
var printer = new ActionBlock<string>(
  s => { Busy(); Console.WriteLine(s); },
  bustagut);

When I pump a dozen or so messages into this on a quad-core machine, Task Manager shows me getting full value for money out of my CPU!

Dataflow is push-friendly

You’ll have noticed that I initiated the dataflow by calling Post (or SendAsync) to submit a data item into a block. This is different from LINQ’s “pull” model. In LINQ, data processing is initiated when I ask for a result. This means dataflow is well suited to applications where data items are coming in unpredictably — for example, handling items coming in from a network or message queue — or even, heaven forbid, a user interface.

TPL dataflow integrates with Reactive Extensions and other observable APIs via the AsObserver and AsObservable extension methods.

Dataflow is messaging

So far this doesn’t seem to do anything more than LINQ (or, at any rate, Parallel LINQ… or at any rate, some sort of bizarre crossbreed of Parallel LINQ and Reactive Extensions… sorry, I’ll come in again). Let’s build it up into more of a messaging system by adding in a broadcast block. Broadcast takes an input and sends it to potentially multiple outputs. So now we can take each data item and perform multiple operations on it in parallel — something not easily possible in LINQ.

var splitter = new BroadcastBlock<string>(s => s);
var helloifier = new TransformBlock<string, string>(s => "Hello, " + s);
var printer = new ActionBlock<string>(s => Console.WriteLine(s));
var businessifier = new TransformBlock<string, string>(s => "Dear " + s);
var emailer = new ActionBlock<string>(s => EmailToBoss(s));
 
splitter.LinkTo(helloifier);
splitter.LinkTo(businessifier);
helloifier.LinkTo(printer);
businessifier.LinkTo(emailer);

Now each input is both printed to the console and emailed. A simple use case for this might be a logging system where messages are stored locally in a CSV file and also uploaded to a Web service.

And once again, the two branches of the dataflow run in parallel. Each block processes messages independently, so the various transformations and actions can all go at their own pace.

Chunky versus chatty

So far I’ve considered data items in isolation. But when processing involves accessing a remote or expensive resource, processing each data item as it comes in may result in inefficient, chatty communication. It may be more better to batch up a number of data items and submit them together. No problem — just reach for the batch block.

var businessifier = new TransformBlock<string, string>(s => "Dear " + s);
var batcher = new BatchBlock<string>(5);
var emailer = new ActionBlock<string[]>(s => EmailToBoss(s));  // Action now takes array of string
// ...
businessifier.LinkTo(batcher);
batcher.LinkTo(emailer);

Now the email method will be called only when there are five pending data items waiting to be processed, and all five will be passed to the email method in one go.

One complication with this is that a batch block doesn’t know when the stream of data has dried up and therefore won’t automatically flush an incomplete batch. For this to work we need to do two things: first, we need to tell the dataflow network when we have no more input; and second, we need to propagate this through the network to the batch block. To do the first, call the Complete() method on the input block; to do the second, specify a DataflowLinkOptions with PropagateCompletion = true on each link:

businessifier.LinkTo(batcher, new DataflowLinkOptions { PropagateCompletion = true });
batcher.LinkTo(emailer, new DataflowLinkOptions { PropagateCompletion = true });
 
for (int i = 0; i < 13; ++i) {
  splitter.SendAsync("world " + i);
}
splitter.Complete();  // no more data to come

Another approach could be to have a watchdog that periodically calls BatchBlock.TriggerBatch — this would also ensure that batches are delivered in a timely way even if the rate of data items is very low.

Add some dynamism to your dataflow

An interesting feature of dataflow compared to LINQ is that dataflow blocks can be linked and unlinked at run time. The LinkTo method returns an IDisposable which, when disposed, deletes the link. This means you can dynamically update your processing flow at run time depending on resource availability, pricing, varying output requirements, etc. You can even imagine giving users a simple diagramming tool for building their own analysis dataflows using transformation, aggregation and filtering blocks.

Conclusion

The examples of dataflow I’ve shown here are very trivial. But hopefully you can see that it provides a flexible way of processing asynchronous messages, based on messaging principles rather than operating directly on sequences and scaling nicely to multiple cores. TPL dataflow is part of .NET 4.5 so if you want to have a play with it just grab the Visual Studio 11 beta and give it a go!



Data Products Visual Controls Community Store
LightSpeed ORM
NHibernate Designer
SimpleDB Tools
SharePoint Tools
WPF Elements
WPF Diagrams
Silverlight Elements
Forums
Blog
Register
Login
Subscribe to newsletter
Buy Now
My Account
Volume Discounts
Purchase Orders
Contact Us