Micro-ORMs for .NET Compared – Part 3

This is the final part of a 3-part series comparing micro-ORMs.  We’ve already seen Dapper and Massive.  Now it’s time for PetaPoco.

PetaPoco

Website: http://www.toptensoftware.com/petapoco/
Code: https://github.com/toptensoftware/petapoco
NuGet: http://nuget.org/packages/PetaPoco

Databases supported: SQL Server, SQL Server CE, Oracle, PostgreSQL, MySQL
Size: 2330 lines of code

Description

PetaPoco was, like the website states, “inspired by Rob Conery’s Massive project but for use with non-dynamic POCO objects.”  A couple of the more notable features include T4 templates to automatically generate POCO classes, and a low-friction SQL builder class

Installation

There are two packages available to install: Core Only and Core + T4 Templates.  I chose the one with templates, which raises a dialog with the following message:

“Running this text template can potentially harm your computer.  Do not run it if you obtained it from an untrusted source.”

PetaPoco has a click-to-accept Apache License.  If your project is a console application, you’ll need to add an App.config file.

Usage

Because PetaPoco uses POCOs, it looks more like Dapper than Massive at first glance:

class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
}

class Program
{
    private static void Main(string[] args)
    {
        var db = new Database("northwind");
        var products = db.Query("SELECT * FROM Products");
    }
}

There is also experimental support for “dynamic” queries if you need them:

var products = db.Query("SELECT * FROM Products");

PetaPoco has a lot of cool features, including paged fetches (a wheel I’ve reinvented far too many times):

var pagedResult = db.Page(sql: "SELECT * FROM Products",
    page: 2, itemsPerPage: 20);

foreach (var product in pagedResult.Items)
{
    Console.WriteLine("{0} - {1}", product.ProductId,
        product.ProductName);
}

While POCOs give you the benefit of static typing, and System.Dynamic frees you from the burden of defining all your objects by hand, templates attempt to give you the best of both worlds.

The first thing you have to do the use templates is ensure that your connection string has a provider name.  Otherwise the code generator will fail.  Then you must configure the Database.tt file.  I changed the following lines:

ConnectionStringName = "northwind";  // Uses last connection string in config if not specified
Namespace = "Northwind";

When you save it, you might get a security warning because Visual Studio is about to generate code from the template.  You can dismiss the warning if you haven’t already.

Now you can use the generated POCOs in your code:

var products = Northwind.Product.Query("SELECT * FROM Products");

First Impressions

PetaPoco is surprisingly full-featured for a micro-ORM while maintaining a light feel and small code size.  There is too much to show in a single blog post, so you should check out the PetaPoco website for a full description of what this tool is capable of.

Final Comparison

All of these micro-ORMs fill a similar need, which is to replace a full-featured ORM with something smaller, simpler, and potentially faster.  That said, each one has its own strengths and weaknesses.  Here are my recommendations based on my own limited testing.

You should consider… If you’re looking for…
Dapper Performance, proven stability
Massive Tiny size, flexibility
PetaPoco POCOs without the pain, more features
Advertisement

Micro-ORMs for .NET Compared – Part 2

This is Part 2 of a 3-part series.  Last time we took a look at Dapper.  This time we’ll see what Massive has to offer.

Massive

Website: http://blog.wekeroad.com/helpy-stuff/and-i-shall-call-it-massive
Code: https://github.com/robconery/massive
NuGet: http://www.nuget.org/packages/Massive

Databases supported: SQL Server, Oracle, PostgreSQL, SQLite
Size: 673 lines of code

Description

Massive was created by Rob Conery.  It relies heavily on the dynamic features of C# 4 and makes extensive use of the ExpandoObject.  It has no dependencies besides what’s in the GAC.

Installation

Unlike Dapper and PetaPoco, Massive does not show up in a normal NuGet search.  You’ll have to go to the Package Manager Console and type “Install-Package Massive -Version 1.1” to install it.  If your solution has multiple projects, make sure you select the correct default project first.

If your project is a console application, you’ll need to add a reference to System.Configuration.

Usage

Despite its name, Massive is tiny.  Weighing in at under 700 lines of code, it is the smallest micro-ORM I tested.  Because it uses dynamics and creates a connection itself, you can get up and running with very little code indeed:

class Products : DynamicModel
{
    public Products() : base("northwind", primaryKeyField: "ProductID") { }
}

class Program
{
    private static void Main(string[] args)
    {
        var tbl = new Products();
        var products = tbl.All();
    }
}

It’s great not having to worry about setting up POCO properties by hand, and depending on your application, this could save you some work when your database schema changes.

However, the fact that this tool relies on System.Dynamic is also its biggest weakness.  You can’t use Visual Studio’s Intellisense to discover properties on returned results, and if you mistype the name of a property, you won’t know it until runtime.  Like most things in life, there are tradeoffs.  If you’re terrified of “scary hippy code”, then this could be a problem.

First Impressions

Massive is very compact and extremely flexible as a result of the design choice to use dynamics.  If you’re willing to code without the Intellisense safety net and can live without static typing, it’s a great way to keep your data mapping simple.

Continue to Part 3…

Micro-ORMs for .NET Compared – Part 1

Recently, I have been made aware of a lightweight alternative to full-blown ORMs like NHibernate and Entity Framework.  They’re called micro-ORMs, and I decided to test-drive a few of the more popular ones to see how they compare.

Each of the tools listed here are small and contained within a single file (hence the “micro” part of the name).  If you’re adventurous, it’s worth having a look at the code since they use some interesting and powerful techniques to implement their mapping, such as Reflection.Emit, C# 4 dynamic features, and T4 templates.

The Software

Dapper

Website: http://code.google.com/p/dapper-dot-net/
GitHub: https://github.com/SamSaffron/dapper-dot-net
NuGet: http://nuget.org/packages/Dapper

Databases supported: Any database with an ADO.NET provider
Size: 2345 lines of code

Description

Dapper was written by Sam Saffron and Marc Gravell and is used by the popular programmer site Stack Overflow.  It’s designed with an emphasis on performance, and even uses Reflection.Emit to generate code on-the-fly internally.  The Dapper website has metrics to show its performance relative to other ORMs.

Among Dapper’s features are list support, buffered and unbuffered readers, multi mapping, and multiple result sets.

Installation

In Visual Studio, use Manage NuGet Packages, search for “Dapper”, and click Install.  Couldn’t be easier.

Usage

Here we select all rows from a Products table and return a collection of Product objects:

class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
}

class Program
{
    private static void Main(string[] args)
    {
        using (var conn = new SqlConnection("Data Source=.\\SQLEXPRESS;
            Initial Catalog=Northwind;Integrated Security=SSPI;"))
        {
            conn.Open();
            var products = conn.Query<Product>("SELECT * FROM Products");
        }
    }
}

As you can see from the example, Dapper expects an open connection, so you have to set that up yourself.  It’s also picky about data types when mapping to a strongly typed list.  For example, if you try to map a 16-bit database column to a 32-bit int property you’ll get a column parsing error.  Mapping is case-insensitive, and you can map to objects that have missing or extra properties compared with the columns you are mapping from.

Dapper can output a collection of dynamic objects if you use Query() instead of Query<T>():

    var shippers = conn.Query("SELECT * FROM Shippers");

This saves you the tedium of defining objects just for mapping.

Dapper supports parameterized queries where the parameters are passed in as anonymous classes:

    var customers =
        conn.Query("SELECT * FROM Customers WHERE Country = @Country
            AND ContactTitle = @ContactTitle",
        new { Country = "Canada", ContactTitle = "Marketing Assistant" });

The multi mapping feature is handy and lets you map one row to multiple objects:

class Order
{
    public int OrderId { get; set; }
    public string CustomerId { get; set; }
    public Customer Customer { get; set; }
    public DateTime OrderDate { get; set; }
}

class Customer
{
    public string CustomerId { get; set; }
    public string City { get; set; }
}

...

var sql =
    @"SELECT * FROM
        Orders o
        INNER JOIN Customers c
            ON c.CustomerID = o.CustomerID
    WHERE
        c.ContactName = 'Bernardo Batista'";

var orders = conn.Query<order, customer,="" order="">(sql,
    (order, customer) => { order.Customer = customer; return order; },
    splitOn: "CustomerID");

var firstOrder = orders.First();

Console.WriteLine("Order date: {0}", firstOrder.OrderDate.ToShortDateString());

Console.WriteLine("Customer city: {0}", firstOrder.Customer.City);

Here, the Customer property of the Order class does not correspond to a database column.  Instead, it will be populated with customer data that was joined to the order in the query.

Make sure to join tables in the right order or you may not get back the results you expect.

First Impressions

Dapper is slightly larger than some other micro-ORMs, but its focus on raw performance means that it excels in that area.  It is flexible and works with POCOs or dynamic objects, and its use on the Stack Overflow website suggests that it is stable and well-tested.

Continue to Part 2…

Learning and Staying Current in .NET Development, Part 2

Here are more ways to build and supplement your programming knowledge.

Stack Overflow

stackoverflow.com is a free programming question and answer site.  Search the existing database or ask and answer questions to build reputation points.  Lots of talented developers commit their brainpower to making the stackoverflow community great, so it’s worth checking out.

Personal projects

Always have a personal project that you enjoy working on, and make sure to write code every day, even when your job doesn’t require it.  If you don’t like programming enough to do it outside of work, you may want to reconsider if software development is right for you.

Open source projects

Contributing to open source projects helps you demonstrate your abilities to prospective employers because it makes your work easily accessible.  It also shows that you’re self-motivated and committed to your own education.  SourceForge.net is currently the largest open source development Web site, while CodePlex is hosted by Microsoft, and freshmeat.net indexes Unix and cross-platform software.

Blogs

Read developer blogs to see what others in the industry are up to.  NOOP.NL maintains a list of the top 200 blogs for developers.  That should keep you busy for a while.

Developers on Twitter

What goes on in the minds of other programmers?  What are their daily routines like, and what do they choose to share with the world?  Much like the list of top blogs, NOOP.NL maintains a list of top developers to follow on Twitter.

Your own blog

Writing your own technical blog can make you a better developer and help you earn the respect of your peers.  Why?  Because making a good programming blog is hard.  In order to write authoritatively on any subject, you should know that subject inside and out.  Just coming up with blogging topics can be a challenge.  If you’re having trouble, read the advice of other technical bloggers.

Tweet about programming

Rather than just read about other people’s lives, open a Twitter account and try to write something programming-related every day.  It will force you to read the news and think about what’s interesting.  If you don’t want to bore your followers, that is.

Programming competitions

Programming contests help you hone your skills by pitting yourself against other developers.  It’s fun to win, but just participating can help you gauge and improve your abilities.  Check out Google Directory for all kinds of challenges.  TopCoder is one place where the competitions are going on all the time.

User groups

User group meetings are a good place to go for networking.  They can also be an opportunity to practice your public speaking skills.  Teaching others is one of the most effective ways to learn.

Magazines and journals

Magazines like MSDN Magazine and Visual Studio Magazine release monthly issues available in “dead tree format” and online.  You may be able to get subscriptions for free if you’re an industry professional.

Certifications

Although this is a controversial topic, I do see at least some value in studying for and taking certification exams.  Doing so helps you round out your knowledge, and if nothing else it gives structure to your learning and a goal to accomplish.
Whatever you do, don’t delude yourself into thinking that certifications are all you need.  At best they are a supplement to the coding and reading you should already be doing.

Social news sites

“Social” news sites are news sites with a reader-participation element, such as voting on articles.  Digg, Reddit, and Slashdot fall into this category.  While some of the material appearing on these sites is legitimate tech news, there is often a lot of noise to filter through.  It’s up to you whether it’s worth it.

And finally, the #1 most important resource for developers

When in doubt, Google.  The search engine is such an essential tool that we often take it for granted.  There’s even a site, “let me google that for you“, that pokes fun at those who refuse to perform their own searches.  Don’t underestimate the value of good search skills.  Nobody knows everything, but finding new information efficiently is fundamental to job performance.  Take a look at Google’s search tips if you haven’t already.

Learning and Staying Current in .NET Development, Part 1

This series lists some of the resources I use to educate myself and stay informed about new technologies.  Take a look if you’re a fledgling developer just starting out, or if you’re simply looking for a new way to keep up-to-date.

These are mainly aimed at the Microsoft development stack, but many are transferable to other platforms.

Microsoft resources

MSDN Flash Developer Newsletter

You can subscribe to MSDN Flash if you want to get news delivered directly to your inbox, or you can just go to the Web site and view the latest issue in your browser.

MSDN Events and Webcasts

Check to see if Microsoft has any in-person events near you.  The presentations are informative and you’ll get the opportunity to network with other local developers.  Sometimes they even give out free stuff like books or software licenses.

The event portal also links to various Webcasts in case there aren’t any live events in your region.

Channel 9

Channel 9 is a community for learning, and a place to get videos, podcasts, and screencasts. You can also watch shows and participate in the forums. There is a ton of content here, and there’s always something new.

DreamSpark

If you’re a student, DreamSpark will get you free access to all sorts of developer tools that would otherwise be prohibitively expensive.  Visual Studio, SQL Server, and Expression Studio are just some of the products offered.

Beta software

Don’t underestimate the value of downloading software while it’s still in beta.  Visual Studio in particular is known for it’s very high-quality pre-release versions.  A good way to guarantee you don’t fall behind is to become an early adopter.

Books

Even in an increasingly online world, books are ideal for assimilating large amounts of information at once.  Do yourself a favor: take a break from clicking and start flipping pages for a while instead.

The Pragmatic Bookshelf

Pragmatic books are concise, well-written, and authored by people who are clearly passionate about the subject matter.

O’Reilly

O’Reilly has historically published some of the best technology books available, although their consistency has declined somewhat in recent years.

Classics

The Mythical Man-Month

Provides several insightful essays like “The Mythical Man-Month”, “The Second-System Effect”, and “No Silver Bullet”.  A must-read, even if it is showing its age in some parts.

Design Patterns: Elements of Reusable Object-Oriented Software

Also known as the “Gang of Four” (GoF) book, Design Patterns is full of elegant solutions to commonly occurring problems in software design.

Other books I’ve read and recommend

C# in Depth: What you need to master C# 2 and 3 by Jon Skeet
This is for serious C# developers who already have a background in the language.  Skeet’s thorough coverage, attention to detail and precise wording make this an awesome learning tool and reference.  The second edition is due out in August.

The Passionate Programmer: Creating a Remarkable Career in Software Development by Chad Fowler

More inspirational than technical, this book offers numerous tips for becoming a great developer.

Coders at Work by Peter Seibel
Peter Seibel interviews 15 notable programmers.  I’m only a few chapters into this one so far, but it’s fascinating to probe the minds of those who have been so influential in our industry.

Joel on Software: And on Diverse and Occasionally Related Matters That Will Prove of Interest to Software Developers, Designers, and Managers, and to Those Who, Whether by Good Fortune or Ill Luck, Work with Them in Some Capacity by Joel Spolsky

Joel is known in part for his widely read blog posts, several of which have been bound together here in book form.  And yes, that really is the subtitle.

Hackers and Painters: Big Ideas from the Computer Age by Paul Graham

It’s interesting to note Graham’s support for Lisp, and the increased adoption of Lisp-like features into new languages since this was written.

The Cathedral and the Bazaar: Musings on Linux and Open Source by an Accidental Revolutionary by Eric S. Raymond

If you struggle to find anything new while reading this book, it’s only because it’s been such an enormous influence over the past decade.

Just for Fun: The Story of an Accidental Revolutionary by Linus Torvalds

Any developer who remembers tinkering with code at a very young age will relate with nostalgia to Torvalds’ geekiness.  This story is indeed fun.

Hackers: Heroes of the Computer Revolution by Steven Levy

Ever wonder how hacking began?  Real, true hacking that started around the 1950’s?  Hackers offers a peek inside the world of those who lived it.

Gödel, Escher, Bach: An Eternal Golden Braid by Douglas R. Hofstadter

This is not a programming book, but a clever, philosophical work of art.  It’s not for everyone, but if you have a curious and analytical mind you might enjoy it.

Visual Studio 2010 Helps You Grok Other People’s Code Quickly

Have you recently started a new job or project where you need to get up to speed on an existing code base rapidly?  Earlier versions of Visual Studio added features like the Class Designer.  Now, VS 2010 provides several more tools to assist you.

View Call Hierarchy

“Find All References” not cutting it? Somewhat like a design-time call stack, the call hierarchy helps you visualize program flow much more easily.

View Call Hierarchy
View Call Hierarchy

A bit of trivia: View Call Hierarchy will only let you drill down into a recursive call once before showing the message “Further expansion is not supported for recursive calls”.

Sequence Diagrams

Here’s another context menu item that you can get by right-clicking on a method. You can reverse engineer your code to get an automatically generated sequence diagram.

Sequence Diagram
Sequence Diagram

Incidentally, this screenshot also shows another cool feature of VS 2010: detachable tabs. You can even detach code tabs.

Reading code that you didn’t write (or wrote a long time ago and forgot how it works) is one of the biggest challenges facing developers. It’s nice to see Microsoft building a solution to this problem into its flagship development tool.

Getting Code Contracts to Work in Visual Studio 2010 RC

Microsoft released Visual Studio 2010 RC to the public on Wednesday along with .NET Framework 4.  One of the new framework features is Code Contracts.

Contracts, like assertions, express assumptions in your code by testing conditions.  For example, the following code requires someParameter to have a value greater than zero or a failure message is displayed:

using System;
using System.Diagnostics.Contracts;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DoSomething(0);
            Console.ReadLine();
        }

        static void DoSomething(int someParameter)
        {
            Contract.Requires(someParameter > 0, "someParameter must be greater than zero.");
            Console.WriteLine("Success");
        }
    }
}

Code Contracts surpass assertions with their ability to do static checking.  They can detect contract violations during a build without even running your code.  They’re also tailored for specifying method-boundary contracts (preconditions and postconditions) while assertions are not.

I assumed contracts would work out of the box, but unfortunately that’s not the case.  .NET 4 does include the System.Diagnostics.Contracts namespace and allows you to write contract-based code, but it won’t do anything unless you install Code Contracts separately.

Download Code Contracts from Microsoft DevLabs

After the install you’ll see a new tab in your project properties called “Code Contracts”.  There you can specify Runtime Checking, Static Checking or both.

Enabling contract checking
Enabling contract checking

Note that static checking is only available in the Premium Edition, which will only install if you have VS 2010 Premium or Ultimate.  The barrier to entry here is too high, in my opinion.  Have a look now before the release candidate expires and these features are out of reach to the average developer.