The beauty that are anonymous methods
I recently came to see code, that used anonymous methods in a very elegant fashion. As very simplified example:
using System; using System.Collections.Generic; namespace ConsoleApplication2 { class Program { static void Main ( string[] args ) { new List<string> { "a", "b", "c", "d" }.ForEach( print => Console.WriteLine( print ) ); } } } |
Create Elegant Code With Anonymous Methods, Iterators, And Partial Classes is an article on MSDN which is a good starting point. Used wisely on a chosen place, it makes the code short and readable. Going crazy makes it essentially unmaintainable. As for me, I think I should get more familiar with that along with LINQ and the ideas behind.
EF: Using HierarchyId with EntityFramework
While evaluating EntityFramework again for a possible use in a new project I decided to tackle HierarchyId support first. The sad news first: there is no built-in way to work with HierarchyIds. The same goes for spatial data, at least for the time being. Both data types are user defined data types, which makes it hard to nearly impossible for a ORM to be database agnostic and supporting that type. Julie Lerman (she has written the well known Programming Entity Framework book) has published an article together with Jason Follas) how to read spatial data (note: the Entity Framework June 2011 CTP introduced a much more streamlined, integrated way of doing this). Essentially this should be possible with HierarchyId, too.
To setup my testing I created a EmployeeData table with data in a new SQL Server 2008 R2 database (I don’t like fiddling in existing databases, so I create and drop test databases frequently). I used the sample code from here, as I’m as lazy as a developer should be. Note: there is a download link at the end of the page. It will save you some time, as the double colons between hierarchyid and GetRoot() aren’t visible on the page and you’ll have to fill them in and add a primary key to the table. Latter is important, as EF doesn’t work on key-less tables.
Data setup, now we need to make EF happy. According to the aforementioned blog entry you need to cast to a binary column, this is best done with a view.
The view’s code is straightforward, once you know which type you should use:
CREATE VIEW [dbo].[EmployeeDemoView] AS SELECT CONVERT( [varbinary](MAX), OrgNode, 0) OrgNode, EmployeeID, LoginID, Title, HireDate FROM dbo.EmployeeDemo |
Now I created a simple console application and added a reference to EF using NuGet (if you don’t know this, do yourself a favor and learn it – it’ll save you tons of time). Add a new model and connect it to the database. I’ve omitted the table, just went for the view.
All columns were there, moved on to coding. A bit of googling and looking into the SQL Server types unveiled the Read method of SqlHierarchyId. What I had to learn, was to successfulle read the stream, the variable has to be initialized as a Null SqlHierarchyId. So my testing looked like this:
using ( ConsoleApplication1.MyDataContextEntities ctx = new MyDataContextEntities() ) { var employees = ctx.EmployeeDemoView.ToList(); foreach ( var item in employees ) { var hierarchyID = Microsoft.SqlServer.Types.SqlHierarchyId.Null; var loginID = item.LoginID; using ( var stream = new System.IO.MemoryStream( item.OrgNode ) ) { using ( var rdr = new System.IO.BinaryReader( stream ) ) { hierarchyID.Read( rdr ); } } Console.WriteLine( "{0},{1}", loginID, hierarchyID ); } } |
There is no way to query for an HierarchyId, but at least you can use it.
Visual Studio Addons
I’m using Visual Studio and event though it’s forcing me to restart it from time to time, I’m still the opinion it’s one the best IDE available currently. One reason for that, is it’s flexibility to have more functionality added by plugins and extensions. I’m going to list the one’s I’m using here and in upcoming posts. For me as a checlist when setting up my PC sometime in the future, for others as a way to find new ones.
I’m going to start with those on my home computer:
- DevExpress CodeRush and DevExpress Refactor! Pro
- NuGet
- Power Productivity Tools
Plugins adding functionality to DX:
- CR_Documentor
- DX_StackNav
- DX_InterfaceNav
- DX_GenerateProxy
- CR_StringFormatter
- CR_BlockPainterPlus
Theme resources
You can find information about theme resources when programming for WP7 here:
http://msdn.microsoft.com/en-us/library/ff769552%28v=vs.92%29.aspx
XPO and a plugin based application architecture
Using Devexpress XPO in a plugin based application
When writing an application that extends using plugins, you might come to the point where not only the logic,
but also the data has to be enriched. Without changing the main datastructure an associtaion using the Association
attribute is not possible. I decided to go without referential integrity, which is suboptimal.
For this sample we imagine an application that manages books ( reduced to Name and Author). Optionally via Plugin
it should be able to manage genres and thei books in the genres.
Let’s have a look at the Book class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using System; using DevExpress.Xpo; namespace XpoPluginDemonstration.DataLibrary1 { public class Book : XPObject { private string _Name; private string _Author; public string Name { get { return _Name; } set { SetPropertyValue( "Name", ref _Name, value ); } } public string Author { get { return _Author; } set { SetPropertyValue( "Author", ref _Author, value ); } } public Book( Session session ) : base( session ) { } } } |
For everyone done some work with YPO this is obvious, and even for those never seen XPO before, the code
should be obvious.
Now, if we look at the second dll, we have a Genre class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using DevExpress.Xpo; namespace XpoPluginDemonstration.DataLibrary2 { public class Genre : XPObject { private string _Name; [Association( "Genre-DL2Books" )] public XPCollection<DL2Book> DL2Books { get { return GetCollection<DL2Book>( "DL2Books" ); } } public string Name { get { return _Name; } set { SetPropertyValue( "Name", ref _Name, value ); } } public Genre( Session session ) : base( session ) { } } } |
The not so obvious thing here is, that it does not reference the Book class nut a DL2Book class.
The DL2Book class is the link between the plugin and the main application’s schema. It looks like
this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System; using DevExpress.Xpo; using XpoPluginDemonstration.DataLibrary1; namespace XpoPluginDemonstration.DataLibrary2 { public class DL2Book : XPObject { private Genre _Genre; private Book _Book; public Book Book { get { return _Book; } set { SetPropertyValue( "Book", ref _Book, value ); } } [Association( "Genre-DL2Books" )] public Genre Genre { get { return _Genre; } set { SetPropertyValue( "Genre", ref _Genre, value ); } } public DL2Book( Session session ) : base( session ) { } } } |
As you can see, a reference to the main applications data definitoin is required. And no Association is defined
between Book and DL2Book. If you need the referential integrity, this isn’t for you.
The next step is, that something must create the database schema. It’s not the straightforward way, as we do not
know the libraries we’re reading the objects from. Look at some code:
1 2 3 4 5 6 7 | IDataLayer dl = XpoDefault.GetDataLayer( AutoCreateOption.DatabaseAndSchema ); XpoDefault.Session = new Session( dl ); List<Assembly> assemblies = new List<Assembly>(); assemblies.Add( typeof( Book ).Assembly ); assemblies.Add( typeof( Genre ).Assembly ); XpoDefault.Session.UpdateSchema( assemblies.ToArray() ); XpoDefault.Session.CreateObjectTypeRecords( assemblies.ToArray() ); |
The interesting stuff hiere are lines 3 onwards. We collect all plugins ( as well as the main applications definition )
in a list of assemblies. Using the ToArray function we transform it into an array and provide all required information
to XPO. The sample project directly references all projects, as I haven’t done the UI part of the plugins in it, so
you do not see the usual loop over the file system. You would place that instead of lines four and five.
Usage is then rather simple and demonstrated using a small console application:
1 2 3 4 5 6 7 | foreach ( Genre genre in new XPQuery<Genre>( XpoDefault.Session ).ToList() ) { Console.WriteLine( String.Format( "Found genre: {0}", genre.Name ) ); foreach ( DL2Book dL2Book in genre.DL2Books ) { Console.WriteLine( String.Format( " Contains the book {0} from {1}", dL2Book.Book.Name, dL2Book.Book.Author ) ); } } |
Output of the program with some data generated:
1 2 3 4 5 | Found genre: Roman Contains the book Sherlock Holmes from Sir Arthur Conan Doyle Contains the book Emil und die Detektive from Erich Kästner Found genre: Science Fiction Contains the book Salvation's Reach from Dan Abnett |
Solution download here.
WPF Tutorial.net
Found a nice site that has a focus on WPF: WPF Tutorial.net. If you search WPF samples and help, this might be a good stop.

