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.

Nightly news, 6 April 2012

By the time you read this, we’ll be off enjoying the long weekend, so consider this a message from the dusty past about that great question of the day: what’s new in this week’s nightly builds.

LightSpeed

  • If you’ve got an aggregate in a where clause on a grouping statement, we can now translate that to a HAVING clause on the SQL query
  • Fix for an issue where the same association is declared in multiple leaves of a STI hierarchy with different reverse associations
  • Clearer error message when a DiscriminatorAttribute has no Attribute value
  • Improved support for expressing properties of SQL Server 2008 spatial types in queries. We’ve also made some improvements around SqlDouble to Double conversion.
  • Fix for error when several threads raced to be the first to execute the same LINQ query, and the LINQ query involved a closure
  • Fixed an issue where a full text search could return an incorrect result if the text search returned a single hit, and that entity was already in the identity map, and there was a QueryExpression filter in addition to the full text search, and the entity in the identity map didn’t conform to the QueryExpression filter. I hope you’re paying attention to this, because there’ll be a quiz later.
  • Initial support for generic entity types, which allow you to use the same utility entity type (such as Permission or AuditRecord) in associations with multiple kinds of other entities
  • You can now specify a DisconnectedDisplayNamedStrategy on ValidationContext for use on entities which are not part of a unit of work

WPF Elements

  • DataGrid automatic column sizing and star sizing
  • Support for read-only columns when using a DataTable as the ItemsSource of a DataGrid
  • Added DataGrid.HighlightedItem property and associated change event and method
  • Added DataGrid.RowHeaderTemplate so you can control the appearance of row ‘headers’ (those little doodads at the left of each row. You know). You can use this for things like row numbering.
  • DataGridWrapper now has a property for retrieving the encapsulated DataTable
  • Fixed an issue with rendering of the DataGrid frozen column shadow
  • We now re-render charts when the Series collection changes
  • Added IsSliderVisible option to show sliders on chart axes for panning and zooming. You can also style the sliders using the (wait for it) SliderStyle property.

Web Workbench

  • Fix for Less compiler error is the file name or containing folder contained a single quote

NHibernate Designer

  • Added ‘formula’ option for entity properties computed in SQL
  • Added support for one-way associations
  • Added DataMember options for one-to-many associations

You know the drill — free editions from the Downloads page, full editions from the store. Enjoy!

Using T4 templates with the NHibernate Designer

The NHibernate Designer is a great way to design data models for use with the NHibernate object-relational mapper. But once you’ve captured your data model, you may be interested in generating other code from it — anything from data transfer objects (DTOs) right through to scaffolding for a simple admin site. In some cases you can do this by editing the designer’s NVelocity templates, but sometimes you want to generate content that doesn’t fit in a C# or VB file, or maybe you just don’t like NVelocity. (I can sympathise with that.) Fortunately, you can use Visual Studio’s standard T4 templating system to do your own code generation off a NHibernate model. Let’s dive in!

Creating the template

To create a T4 template, add a new item to your project and choose Text Template. This gives you an empty starter T4 file.

Next, you need to hook the template up to the NHibernate Designer DLLs. You do this in two parts. First, you add the following incantation to the template directive:

<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" ... #>

Don’t worry about what this means — it’s just a bit of plumbing to bring in the same Visual Studio subsystem that the NHibernate Designer sits over. Next, you add a couple of assembly references:

<#@ assembly name="Mindscape.NHibernateModelDesigner.DataModel.dll" #>
<#@ assembly name="Mindscape.NHibernateModelDesigner.Dsl.Mapping.dll" #>

Also, by default the T4 template generates an output file with a .txt extension. I’m going to stick with this to keep the example simple, but more usually, you’ll want something more meaningful such as .cs or .aspx. If so, change the output directive:

<#@ output extension=".cs" #>

Finally, you need to hook your template up to your NHibernate model, using a NHibernateModel directive. I’m going to assume we have a file called StoreModel.nhmodel, so my directive looks like this:

<#@ NHibernateModel processor="NHibernateModelDirectiveProcessor"
                    requires="fileName='StoreModel.nhmodel'" #>

Now everything is ready, we can start to generate some code.

Populating the template

For this simple example, my template is just going to generate a list of the entities in the model, in plain text format. (I dunno, maybe so you can print it out extra big so marketing can understand it.) This is a job for a simple foreach loop over the collection of entities, generating the name each time. So my template body looks like this:

Entities in model:
<#
  foreach (/* HOW DO I GET THE LIST OF ENTITIES? */)
  {
#>
* <#= /* HOW DO I GET THE ENTITY NAMES? */ #>
<#    
  }
#>

As you can see there are a couple of things I need to figure out about working with the NHibernate model. The first is how to get the list of entities. Well, thanks to the NHibernateModel directive, the template contains a member variable called Model which represents the NHibernate model. The model has an Entities collection which we can iterate over, so that solves that problem. The second thing is how to get an entity’s name. It turns out that the Entities collection contains Entity objects, and Entity defines a Name property. So that’s sorted too. Here’s the final template body:

Entities in model:
<#
  foreach (Entity entity in this.Model.Entities)
  {
#>
* <#= entity.Name #>
<#    
  }
#>

What are these Entity objects and how am I meant to know about them?

Note that the Entity objects in the NHibernate model aren’t instances of objects materialised from the database. They are the entity definitions on the designer. For example, if a model defines Customer, Product and Order entity classes, then the Model.Entities collection will contain three Entity objects corresponding to these three classes. Everything we’re talking about in this post is happening in the so-called ‘metamodel’ — the way the designer talks about NHibernate models, not about live NHibernate objects.

The bigger question though is how I knew that Model had an Entities property and that Entity had a Name property. Where is this stuff documented? Well — ahem — it isn’t. For the time being, you need to ask in the forums, or work it out for yourself. Fortunately, it’s usually pretty easy to guess. For collections, go to the NHibernate Model Explorer (View > Other Windows > NHibernate Model) and look at the folder names. Those are normally your collection names. For scalars, go to the Properties window and look at the setting names. Those are normally your property names. (Again, by ‘property’ I mean a property of the metaobject, not one of the properties you define as part of your domain model. So Entity has properties like Name, TableName, Visibility, etc.) In some cases, the display name doesn’t quite match the class or property name, in which case try looking at the element or attribute name in the .nhmodel file. Be prepared for a bit of exploration, and a bit of trial and error!

Trying it out

Okay, I’ve written my template, so now I’ll add some entities to my model and… nothing happens! Well, one annoying feature of T4 templates is that they don’t automatically re-run when the model changes. You need to choose the Transform All Templates button in the Solution Explorer toolbar to make them re-run. When I do this, the .txt file is regenerated and it contains the output we’d expect:

Entities in model:
* Customer
* Order
* Product

Obviously, this is a simplistic and unrealistic example. (That’s why I think it’s a great fit for marketing.) But using T4 you can generate C# or VB files, ASP.NET files, you name it — the sky’s the limit. If you’ve got a cool idea, download the NHibernate Designer for free and try it out!

Nightly news, 30 March 2012

Ivan is off moonlighting as a luchador today, so its my turn to provide the weekly update. Its mostly been a week of bug fixes and working toward getting WPF Elements 5.1 out the door with a bunch of performance improvements and new features. Meanwhile we continued to beaver away on all the other products of course :) Here’s what’s new in this week’s nightly builds.

JD's box only contained some grainy .gif files and a copy of some poker game

LightSpeed

  • Fix for issue with eager loading when we have a STI hierarchy which has multiple branches where the eager load is on a separate branch to the derived type being worked on
  • Added support for expressing a HAVING clause within core querying engine, use the Group.Having property to apply this

NHibernate Designer

  • Fix for trying to apply a default to MySQL TEXT fields
  • Added support for foreign identity generator

WPF Elements

  • Fixes relating to NaN axis values on some charting controls
  • General performance improvements

Web Workbench

  • Added command line compiler tools for paid customers
  • Added combining for CoffeeScript

As ever, nightly builds of free editions are available from the downloads page, and of full editions from the store.

Nightly news, 16 March 2012

WPF Elements

  • Added DataSeries.IsShownInLegend property to allow series to be excluded from the legend
  • If a type is edited in the property grid through a type converter instead of a TypeEditor, the grid now shows subproperties if the type converter derives from ExpandableObjectConverter
  • Added support for IBindingList as a source for the DataGrid
  • Fixed a bug which made it difficult to display the SchedulerDialog when double-clicking an item
  • Added DataGridCellEditModeBehavior to specify how the user can cause a DataGrid cell to enter edit mode using the mouse
  • Added new RowAndCell data grid selection mode
  • Improvements to DataGrid keyboard navigation
  • Typing into a DataGrid cell now automatically puts it into edit mode

LightSpeed

  • If a user is editing an entity which is soft-deletable and uses optimistic concurrency checking, and another user deletes it, and the first user then saves their changes, we now raise an OptimisticConcurrencyException
  • Fix for issue where if you queried on a property of an associated entity and that entity was soft-deleted and you were using a naming strategy to map the soft delete column name, it would give you a null reference exception. Bet you didn’t see that one coming
  • Fixed an issue with JSON.NET serialisation
  • Added support for database-side timestamps

NHibernate Designer

  • Added support for creating through tables in the database when the many-to-many association is of List kind

Web Workbench

  • Added support for specifying ‘co-imported’ files in order to include their variables in completion lists and suppress unwanted wigglies from their variables and mixins (use a specially formatted //* ww-expect "filename" comment)
  • Updated Less compiler to 1.3
  • Added Less, Sass and CoffeeScript file templates for Web Site pseudo-projects
  • Improved support for partials naming convention – if you create a file whose name begins with an underscore, it will now default to not compiling (you can turn it back on using the Web Workbench Settings screen)

Nightly builds of free editions are available from the downloads page, and of full editions from the store. Enjoy!

Archives

Join our mailer

You should join our newsletter! Sent monthly:

Back to Top