Archive for the 'Development' Category

Calling Stored Procedures from Entity Framework 6 Code First

Just a quick solution to something I was banging my head against for a while.

If you use the EDMX/Database First way of creating your DbContext, you can import Stored Procedures to your context. The result is something like this:

public virtual ObjectResult<Customer_LoadStatus_Result> Customer_LoadStatus(Nullable<int> customerId)
{
    var customerIdParameter = customerId.HasValue ?
        new ObjectParameter("CustomerId", customerId) :
        new ObjectParameter("CustomerId", typeof(int));
 
    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Customer_LoadStatus_Result>("Customer_LoadStatus", customerIdParameter);
}

If you try to copy this method to your Code First context, you’re likely to get an error saying something like, “The FunctionImport ‘Customer_LoadStatus’ could not be found in the container ‘CustomerDbContext’.” There’s probably a way to register it in the ModelBuilder, but 15min of web searches came up with nothing (maybe my Google-Fu is weak?).

Long story short, it seems you can’t just copy this to your context if you’re using Code First. Instead, do this:

public virtual Customer_LoadStatus_Result Customer_LoadStatus(int? customerId)
{
    var customerIdParameter = customerId.HasValue ?
        new SqlParameter("CustomerId", customerId) :
        new SqlParameter("CustomerId", typeof(int));

    return this.Database.SqlQuery<Customer_LoadStatus_Result>("Customer_LoadStatus @customerId",
        customerIdParameter).SingleOrDefault();
}

As a bonus, in my example I’m just returning the object I expect rather than the wrapped one you’d get from the generated code.

Glimpse Heads Up Display released

Today, Anthony van der Hoorn and Nik Molnar announced the release of a new version of Glimpse with a big new feature – the Heads Up Display.

I’ve been lucky enough to see this new feature grow into its current form and in my opinion, it takes this tool from the “very useful” category into the realm of “must have”.

SSW has been recommending Glimpse for some time.  With the addition of this feature, we now recommend you use it all the time!

The New HUD

Assuming you’re familiar with the previous version of Glimpse, you’ll know that once it’s set up and turned on, you see a small icon on the bottom-right of your screen (Old Glimpse Icon).  Clicking it will expand a big devtools-esque view of what’s happening on your server.  Incredibly useful.

I often keep Glimpse running while I’m in development, and whenever I want to know about what route was hit or how many SQL queries were executed for this page, I’ll click the icon and have a look.

The point is, I have to look.  Glimpse required the developer to actively investigate.  The new Heads Up Display changes the game – now I don’t have to be looking for the cause of a problem, the information is there all the time.  You now have a very powerful and proactive tool at your disposal.

Example Time!

I frequently use Glimpse to verify that a page I’m looking at doesn’t suffer from the dreaded N+1 Selects problem you can get with a lot of ORM tools.  The SQL tab (see Glimpse.Ado and Glimpse.EF) let me see what queries are being run against my SQL server.  If I see a lot, there’s likely to be a problem.

With the new Glimpse HUD, that information is always there whether I’m actively looking for it or not.  While testing one of the pre-release versions of the HUD, I noticed a page on a project I was working on that resulted in 74 SQL queries.  Had I been using the old version of Glimpse, I may not have noticed (I wasn’t working on that page)!

Here’s what I saw (minus the issue):

New Glimpse HUD

Above, you can see the number of Database queries and the time taken for those queries.  In my case, I noticed this number was a really high.  To  investigate further, I can hover over the “Host” section to get some more info.

New Glimpse Expanded

In this example, we can see that not only were there three queries, we actually have three connections.  In my case, the 74 queries were shared over maybe a dozen connections.  Something was going wrong here.  You’ll note we can see lots more information about what’s going on in terms of Controller Actions and Views as well.

As with previous versions, we can click the (new) Glimpse logo to expand Glimpse into its full view, showing us the actual queries that were run against the database.  The UI here has been updated as well and is very clean and “metro-y”.  This is where I could see all the repeated queries that were running against my SQL Server.

New Glimpse Full View

Without the HUD, I probably wouldn’t have noticed there was a problem until much later.  Because the HUD gives me this info in a relatively subtle way, I caught this issue quite quickly.

Summary

Glimpse now has three modes of delivering you data instead of just the one, and the HUD is the big game-changer here.

First, you get a Heads Up Display (HUD) that I’d strongly recommend you keep open at all times while developing.  It lets you monitor the performance of your application without getting in your way.  More importantly, it’s likely to show you issues preemptively rather than waiting for you to investigate.

If you hover over one of the HUD sections, it expands to give you even more info – this lets you investigate a bit further while still staying out of your way for the most part.

Finally, the full view of Glimpse gives you the UI you’re probably used to if you really want to dig deep.

Get it now!

The new version of Glimpse is live on Nuget, but if you want to read more about the new release, head to getglimpse.com or the blog post on the Glimpse Blog.

Getting the Glimpse SQL tab working with Linq to SQL

I’m currently working on an ASP.NET MVC project that’s using Linq to SQL for data access.

As usual, one of my first contributions was adding Glimpse (including Glimpse.MVC4 and Glimpse.Ado), initially as an easy way to confirm my suspicions of the dreaded N+1 problem.

Unfortunately, when I ran it, the SQL tab in Glimpse gave me nothing – Glimpse wasn’t tapping into my data connection.  The issue is Glimpse attaches itself by providing its own GlimpseDbProviderFactory which wraps the standard ones.  This lets it collect information about how you’re using your data connections. Our Linq to SQL implementation wasn’t using this factory so I had to do the work myself.

Here’s how I fixed this issue.  Even if you’re not using Linq to SQL, the solution is fairly generic, so you might find it’ll help you as well.

First, I found the generated Data Context class.  It should be in the .designer.cs file for your dbml.

[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="MyApp")]
public partial class MyAppDataContext : System.Data.Linq.DataContext
{
    private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
    
#region Extensibility Method Definitions
    // snip
#endregion
    
    public MyAppDataContext(string connection) : 
            base(connection, mappingSource)
    {
        OnCreated();
    }
    
    public MyAppDataContext(System.Data.IDbConnection connection) : 
            base(connection, mappingSource)
    {
        OnCreated();
    }
    
    // snip
}

The highlighted lines represent two of the overloaded constructors that can be used to create a context.

Our project had been using the first one by passing in a connection string. To resolve the issue I’m having, I’m going to use the second constructor, passing in our own IDbConnection.

I need to change this:

var context = new MyAppDataContext(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString());

to this:

var context = new MyAppDataContext(
    new GlimpseDbConnection(
        new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString())
    )
);

After pressing F5, everything worked beautifully and we started seeing our SQL queries come through.

All that’s happening is that we’re manually wrapping our connection in a GlimpseDbConnection. In short, if you have control over the creation of the IDbConnection, you can get Glimpse working with very little fuss. Of course, you’ll need to include Glimpse.Ado in the project that calls this constructor.

I’m sure I don’t need to tell you that you should be using Dependency Injection to inject your IDbConnection where required, making it even easier to implement!

Die, Native Apps, Die!

Recently, I’ve been telling anyone who will listen that you should consider writing an HTML5 web app rather than a native mobile app.  The advantages are many and the list of things you can’t do grows smaller by the day.

I spoke on the topic at DDD Sydney earlier in the year, and more recently at Web Directions “What Do You Know” in Brisbane.  If you’d like the slides, they’re available at http://www.damianbrady.com.au/dyrnaa and http://www.devnewsreader.com/about.html respectively; complete with demos.  Check them out – I’d love your comments.

Why choose web apps over native apps?

There are a lot of reasons, and most are obvious.

  1. Users are always on the latest version – no support of old versions
  2. You only have to implement it once, in one language (counting HTML, CSS, and JS as one language of course)
  3. You can choose what to charge and how to charge it
  4. Done properly, web apps work on all devices – even those that don’t exist yet

But they’re slow!

Well no, not necessarily.  I blame Facebook for this misconception.

Facebook famously released an HTML5-based app for iOS and then ditched it in favour of a native app to squeeze more performance out. After all the reporting, the emergent mainstream view was that HTML5 apps simply couldn’t perform.  In reality, the new release was a refresh using a technology closer to the metal as a reaction to consumers screaming out for performance above all else.  Let’s face it, Facebook is not a trivial app in terms of bandwidth and content. There’s a fair bit going on with photos, chat, notifications, etc.

Could Facebook have made the app faster while still using HTML5? Almost certainly, and if they’d leveraged newer HTML5 capabilities as they became available, there definitely would have been improvements.

But would it have appeased the masses? Maybe, but we’ll never really know.

But web apps can’t do X!

Quite possibly not, no.

Well… unless you’re talking about using touch events, orientation, geolocation, hardware-accelerated graphics, local data storage, offline operation, home-screen icons, audio and video, sending emails or making phone calls. So probably yes… yes they can.

Sure, there’s gaps in there. A web app can’t use your phone contacts, it can’t play your music, and it can’t (quite) use the camera.

…Yet

Yet?

There’s a very definite trend in the world of HTML and browsers.  Each new browser or mobile OS version slowly chips away a bit more at the list of things a web app can’t do.  Surprisingly, Apple seems to be leading the way to a degree in the mobile space; enabling more and more HTML5 features in Safari with each release.

I say “surprisingly” because Apple has a very captive market in terms of native apps. True or not, the perception exists that neither Android nor Windows Phone have the same quality of apps available in their stores. Certainly they don’t have the quantity. Why then would Apple implement functions in Safari that pave the way for native-quality web apps?  It’s a good question, and I’m not sure I have the answer. Maybe it’s just the constant drive to stay in front.

Grooveshark

Very recently, Grooveshark rolled out a fully-functional HTML5 version of their site that works beautifully on mobile devices.  They’ve been plagued by problems getting native apps into the official app stores, and this option allows them to bypass the problem altogether.

It’s a truly impressive piece of engineering. If you have a … well… anything… I strongly suggest you go and try it out.  There are some amazing features. For example, (On iOS at least) you don’t even have to keep the browser window open for the music to keep playing.

One small thing… I’d love to see them implement some of the meta and link tags that Apple has made available for iOS devices.  For an example, try adding http://www.devnewsreader.com to your home screen on an iPhone or iPad (warning, it’s quick-demo quality).

Despite being a company that focuses on something not traditionally offered via a web page (streaming music), Grooveshark has chosen HTML5 as the right way to go.  Before sinking time and money into developing native apps for multiple platforms, it’s worth considering whether your app might be a good candidate for a web app as well.

Grooveshark may not be the first high-profile name to try to escape the walled-garden of native apps, but moves like this definitely show the blood in the water (pun totally intended and awesome).

A Generic Repository and Unit of Work Implementation for Entity Framework

You may be familiar with my previous posts describing the implementation of design patterns for Entity Framework.  It started with using generics for lookup tables, and followed with a generic CRUD repository.  This strategy follows along with our SSW rule, Do you use the Repository Pattern for data access.

In the lead up to SSW’s recent Enterprise MVC course, I had lots of discussions with Adam Stephensen and Eric Phan about whether we could do a better job with this pattern.  We’ve come up with what we think is a great solution that includes the Unit of Work pattern as well.

We felt it was really important to separate the domain models, the repositories, and the context; a separation that’s not made by Entity Framework. Doing so gave us some really important benefits.  Testing is made much easier.  For one, we can mock our context enabling us to test our repositories without going back to the database.  We can also mock the repositories to test the code that calls it.

A quick shout-out to Adrian Clark who suggested this separation in the comments last time.

We also used Inversion of Control to inject a context into the repository.  We could have had a reference to each of our repositories in our context, but inverting this relationship meant that we only needed to instantiate those repositories we were actually using.  It means less overhead and a looser coupling between the context and each repository.

First, we create our IUnitOfWork and our IGenericRepository.

public interface IUnitOfWork : IDisposable
{
    DbSet&lt;TEntity&gt; Set&lt;TEntity&gt;() where TEntity : class;

    int SaveChanges();
}
public interface IGenericRepository&lt;TEntity&gt;
  where TEntity : class
{
    IQueryable&lt;TEntity&gt; Select();

    IEnumerable&lt;TEntity&gt; GetAll();

    IEnumerable&lt;TEntity&gt; Where(Func&lt;TEntity, bool&gt; predicate);

    TEntity GetSingle(Func&lt;TEntity, bool&gt; predicate);

    TEntity GetFirst(Func&lt;TEntity, bool&gt; predicate);

    void Add(TEntity entity);

    void Delete(TEntity entity);

    void Attach(TEntity entity);

    void Dispose(bool disposing);

    void Dispose();
}

Then, we create an interface for our specific context. In this example, we have a context with a set of customers. This context is essentially a unit of work, so we’ll inherit that interface.

public interface ICustomerContext : IUnitOfWork
{
    DbSet&lt;Customer&gt; Customers { get; set; }
}

Next, we’ll create a concrete GenericRepository instance. This is very similar to the version in my previous post, but take note of the repository that takes a context. We use this to inject our Unit of Work.

public class GenericRepository&lt;TContext, TEntity&gt; : IGenericRepository&lt;TEntity&gt;
    where TContext : IUnitOfWork
    where TEntity : class
{
    protected TContext _context;
    /// &lt;summary&gt;
    /// Constructor that takes a context
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;context&quot;&gt;An established data context&lt;/param&gt;
    public GenericRepository(TContext context)
    {
        _context = context;
    }

    public IQueryable&lt;TEntity&gt; Select()
    {
        return _context.Set&lt;TEntity&gt;().AsQueryable();
    }

    public IEnumerable&lt;TEntity&gt; GetAll()
    {
        return _context.Set&lt;TEntity&gt;().AsEnumerable();
    }

    public IEnumerable&lt;TEntity&gt; Where(Func&lt;TEntity, bool&gt; predicate)
    {
        return _context.Set&lt;TEntity&gt;().Where(predicate);
    }

    public TEntity GetSingle(Func&lt;TEntity, bool&gt; predicate)
    {
        return _context.Set&lt;TEntity&gt;().Single(predicate);
    }

    public TEntity GetFirst(Func&lt;TEntity, bool&gt; predicate)
    {
        return _context.Set&lt;TEntity&gt;().First(predicate);
    }

    public void Add(TEntity entity)
    {
        if (entity == null)
            throw new ArgumentException(&quot;Cannot add a null entity&quot;);

        _context.Set&lt;TEntity&gt;().Add(entity);
    }

    public void Delete(TEntity entity)
    {
        if (entity == null)
            throw new ArgumentException(&quot;Cannot delete a null entity&quot;);

        _context.Set&lt;TEntity&gt;().Remove(entity);
    }

    public void Attach(TEntity entity)
    {
        if (entity == null)
            throw new ArgumentException(&quot;Cannot attach a null entity&quot;);

        _context.Set&lt;TEntity&gt;().Attach(entity);
    }

    #region IDisposable implementation
    private bool disposedValue;

    public void Dispose(bool disposing)
    {
        if (!this.disposedValue)
        {
            if (disposing)
            {
                // dispose managed state here if required
            }
            // dispose unmanaged objects and set large fields to null
        }
        this.disposedValue = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion
}

Next, we’ll create a concretion for our context using Entity Framework. We’ll inherit DbContext as well as implementing ICustomerContext, and we’ll create both an empty constructor and one that takes a connection string so we can connect to a specific database.

public class CustomerContext : System.Data.Entity.DbContext, ICustomerContext
{
    public CustomerContext() { }

    public CustomerContext(string connectionString) : base(connectionString) { }
}

And that’s all we really need to do.

When we use it, we have to make sure we refer only to our interfaces so we can replace them later if need be.

private ICustomerContext _context;
private IGenericRepository&lt;Customer&gt; _customerRepository;

Ideally, we’d be using Dependency Injection to inject our concretions at runtime, but here’s an example of how you would do it.

_context = new CustomerContext();
_customerRepository = new GenericRepository&lt;ICustomerContext,Customer&gt;(_context);

From there, we can do whatever we need to do with the objects in our repository, and just call SaveChanges() on our context when we’re done. For example:

public ResetCustomerLastLoginDate(int customerId) {
    var customer = _customerRepository.GetSingle(c =&gt; c.CustomerId == customerId);
    customer.LastLoginDate = DateTime.Now;
    _context.SaveChanges();
}

A Generic CRUD Repository for Entity Framework

Update: After a bit more work and discussions with other SSW guys, we’ve put together an updated version of this implementation. Have a read here.

I wrote a post a while ago about using Generics for lookup tables in Entity Framework and I suggested that the idea could be extended to include all objects and CRUD operations.

Well, I’ve put together a generic Repository that can be used in your project to give you a consistent base class for all your repositories. It’s quite long, so sorry about that.

This implementation follows our SSW Rule, Do you use the repository pattern for data access.

public class DataRepository&lt;TContext&gt; : IDataRepository&lt;TContext&gt; where TContext : ObjectContext
{
    // Cached ObjectSets so changes persist
    protected Dictionary&lt;string, object&gt; CachedObjects = new Dictionary&lt;string, object&gt;();
    protected ObjectSet&lt;TEntity&gt; GetObjectSet&lt;TEntity&gt;() where TEntity : EntityObject
    {
        var fulltypename = typeof (TEntity).AssemblyQualifiedName;
        if (fulltypename == null)
            throw new ArgumentException(&quot;Invalid Type passed to GetObjectSet!&quot;);
        if (!CachedObjects.ContainsKey(fulltypename))
        {
            var objectset = _context.CreateObjectSet&lt;TEntity&gt;();
            CachedObjects.Add(fulltypename, objectset);
        }
        return CachedObjects[fulltypename] as ObjectSet&lt;TEntity&gt;;
    }

    protected TContext _context;
    /// &lt;summary&gt;
    /// Constructor that takes a context
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;context&quot;&gt;An established data context&lt;/param&gt;
    public DataRepository(TContext context)
    {
        _context = context;
    }

    /// &lt;summary&gt;
    /// Constructor that takes a connection string and an EDMX name
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;connectionString&quot;&gt;The connection string&lt;/param&gt;
    /// &lt;param name=&quot;edmxName&quot;&gt;The name of the EDMX so we can build an Entity Connection string&lt;/param&gt;
    public DataRepository(string connectionString, string edmxName)
    {
        var entityConnection =
            String.Format(
                &quot;metadata=res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl;provider=System.Data.SqlClient;provider connection string=&quot;,
                edmxName);

        // append the database connection string and save
        entityConnection = entityConnection + &quot;\&quot;&quot; + connectionString + &quot;\&quot;&quot;;
        var targetType = typeof (TContext);
        var ctx = Activator.CreateInstance(targetType, entityConnection);
        _context = (TContext) ctx;
    }

    public IQueryable&lt;TEntity&gt; Fetch&lt;TEntity&gt;() where TEntity : EntityObject
    {
        return GetObjectSet&lt;TEntity&gt;();
    }

    public IEnumerable&lt;TEntity&gt; GetAll&lt;TEntity&gt;() where TEntity : EntityObject
    {

        return GetObjectSet&lt;TEntity&gt;().AsEnumerable();
    }

    public IEnumerable&lt;TEntity&gt; Find&lt;TEntity&gt;(Func&lt;TEntity, bool&gt; predicate) where TEntity : EntityObject
    {
        return GetObjectSet&lt;TEntity&gt;().Where(predicate);
    }

    public TEntity GetSingle&lt;TEntity&gt;(Func&lt;TEntity, bool&gt; predicate) where TEntity : EntityObject
    {
        return GetObjectSet&lt;TEntity&gt;().Single(predicate);
    }

    public TEntity GetFirst&lt;TEntity&gt;(Func&lt;TEntity, bool&gt; predicate) where TEntity : EntityObject
    {
        return GetObjectSet&lt;TEntity&gt;().First(predicate);
    }

    public IEnumerable&lt;TEntity&gt; GetLookup&lt;TEntity&gt;() where TEntity : EntityObject
    {
        return GetObjectSet&lt;TEntity&gt;().ToList();
    }

    public void Add&lt;TEntity&gt;(TEntity entity) where TEntity : EntityObject
    {
        if (entity == null)
            throw new ArgumentException(&quot;Cannot add a null entity&quot;);

        GetObjectSet&lt;TEntity&gt;().AddObject(entity);
    }

    public void Delete&lt;TEntity&gt;(TEntity entity) where TEntity : EntityObject
    {
        if (entity == null)
            throw new ArgumentException(&quot;Cannot delete a null entity&quot;);

        GetObjectSet&lt;TEntity&gt;().DeleteObject(entity);
    }

    public void Attach&lt;TEntity&gt;(TEntity entity) where TEntity : EntityObject
    {
        if (entity == null)
            throw new ArgumentException(&quot;Cannot attach a null entity&quot;);

        GetObjectSet&lt;TEntity&gt;().Attach(entity);
    }

    public void SaveChanges()
    {
        SaveChanges(SaveOptions.None);
    }

    public void SaveChanges(SaveOptions options)
    {
        _context.SaveChanges(options);
    }

    public void Refresh&lt;TEntity&gt;(TEntity entity) where TEntity : EntityObject
    {
        _context.Refresh(RefreshMode.StoreWins, entity);
    }

    public void Refresh&lt;TEntity&gt;(IEnumerable&lt;TEntity&gt; entities) where TEntity : EntityObject
    {
        _context.Refresh(RefreshMode.StoreWins, entities);
    }

    #region IDisposable implementation
    private bool disposedValue;
    protected void Dispose(bool disposing)
    {
        if (!this.disposedValue)
        {
            if (disposing)
            {
                // dispose managed state here if required
            }
            // dispose unmanaged objects and set large fields to null
        }
        this.disposedValue = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion
}

A lot of code to be sure, but you only need one of these. After that, whenever you create a new EDMX, you can create a Repository that inherits from this base repository.

Let’s look at using it for the same AdventureWorks repository I used last time:

An Adventure Works Entity Model

An Adventure Works Entity Model

Here’s how you might implement a repository for this data model:

public class AdventureWorksRepository : DataRepository
{
    public AdventureWorksRepository(string connectionString) : base(connectionString, &quot;AdventureWorksEntities&quot;) { }
}

Yep, seriously. That’s it. Now you have access to all your common CRUD operations (as well as Linq queries) and can do things like this:

var repository = new AdventureWorksRepository(MyConnectionString);

// return all states and provinces
var states = repository.GetAll&lt;StateProvince&gt;();

// get states and provinces with a three letter code
var threeLetterStates = repository.Fetch&lt;StateProvince&gt;()
                                  .Where(s =&gt; s.StateProvinceCode.Length == 3)

// get a customer
var cust = repository.GetSingle&lt;Customer&gt;(c =&gt; c.CustomerID == 1);

// delete that customer
repository.Delete(cust);

// get a contact
var contact = repository.GetSingle&lt;Contact&gt;(c =&gt; c.ContactID == 1);

// edit some properties
contact.Title = &quot;Mr&quot;;
contact.Phone = &quot;61 411 111 111&quot;;

// save all the changes (this will save the customer deletion and the updated contact)
repository.SaveChanges();

So just by inheriting a base repository class, you can get some really powerful behaviour which is specific to your data model.

I’d be interested to hear your thoughts on this technique, particularly if you try it in your own project.

Speaking at QMSDNUG on Tuesday 21st Feb

Just a quick post to let you know I’ll be presenting my “Building Mobile Websites with ASP.NET MVC 3 and 4″ talk at the Qld MSDN User Group meeting on Tuesday the 21st.

Previous versions of this talk have focused mainly on MVC 3 with a nod towards MVC 4. Now that the ASP.Net team have officially launched the beta of ASP.NET MVC 4, I’ll be shifting the focus to the new version.  Out with the old and in with the new!

If you saw the version of this talk I gave at DDD Brisbane last year, don’t be scared off – it’s gone through many, many iterations since then based on the feedback I’ve received.

So if you’re in Brisbane, I’d love for you to come along.  Just RSVP on EventBrite and I’ll see you there!

Horses for Courses (and Jockeys)

I’ve stumbled across a few blog posts lately that talk about why everyone should use one technology over another, or why someone is leaving a particular language for another. Obviously there’s no shortage of evangelical blog posts pushing the merits of one technology and lamenting the poor state of whatever-you-plebs-use.  But this latest spate got me thinking.

Most (good) developers talk about using the most appropriate technology for the job.  At its most basic level that means choosing Objective-C for a resource-hungry iPhone app, or writing your latest facebook-killer application for the web rather than the desktop.  That stuff’s obvious.  The more idealist polyglot programmers will take it further and push Ruby on Rails for web apps with a small budget, or they’ll suggest using RavenDB and deploying to AWS because all you need to do is store and retrieve documents across the web. If you’re in a Windows environment with a team running Scrum, choose TFS, C#, and SQL Server.

So “Horses for Courses” right?

The aim is valid and noble, and it’s certainly one I strive for.  But one thing frequently gets overlooked, and that’s the people on the team (or to stretch the metaphor – the jockeys).

If you have a team of programmers who are very used to writing software using certain technologies, think very carefully about advising them to move to something else. I’m not saying don’t do it (in some cases you really should), but there comes a point where the benefits to be gained by using language X on platform Y with source control Z just aren’t worth the trouble.

Unfortunately, most programmers write code in one way. They use one language, they know one data storage mechanism, and they’ve only ever written applications for one environment.  Maybe in a past life they tried out some other language, and maybe they dabble in HTML occasionally, but they’re only experts at one thing.

You, on the other hand, might look at a set of requirements and decide a NoSQL data store running behind RoR is the “best” solution for this project. Similarly, you recommend using git as the “best” source control system to use. Great. Unless you’re the only one who knows this stuff – then you’re dreaming.  If you have a team of C# developers, you’d want to have a pretty good reason for suggesting they program in a different language. If every other project they’re working on uses TFS, learning git is going to introduce a lot of overhead (initially).  Sometimes, the current way of doing things is the “best” way, even if the idealist in you disagrees.

Now, that’s not to say it’s never a good idea to force a shift within a team.  Consider a team of VB 6 developers who, for the last 15 years, have been dutifully writing VB windows applications with an Access back-end. At what point do you tell them it’s time to move on? (Ideally it would have been at least 5 years ago, but that’s clearly not an option). Assuming you don’t outsource or “refresh” the team, you should strongly suggest they change, but acknowledge that the extra effort they’ll have to put in will increase the work. Also be aware that you’re unlikely to get a quality solution from them if they don’t yet know what they’re doing.

My point is, when choosing the right technology for the job, consider everything, and that includes the skillset of the developers.

With that in mind, blog posts encouraging everybody to stop using .Net because it sucks, or telling them they should never use pure HTML and JS for business apps are just ridiculous. Yes, you might have had an overnight change of heart and now realise language X is the worst thing in the world, but you’re thinking about the specific situations you’ve been in, and developers with specific skills (usually just the individual author). If your whole team can just up and move to Ruby, then fantastic! Say hi to the rainbow coloured unicorns for me!

It’s always good to encourage teams to learn new technologies. It’s occasionally good to force a team to move on, but sometimes the “best” way isn’t the “ideal” way.

How to be a Good TFS Master

How to be a Good TFS Master

How to be a Good TFS Master

I recently gave a talk at the Qld ALM User Group on the topic of “How to be a good TFS Master”.

Hopefully those who turned up got some great tips on how to use TFS more fully, but the main points I hoped people left with were:

Most people only use about 20-30% of the capabilities of TFS

In our experience, the majority of companies using TFS are using it for source control only.  SSW helps teams get closer to using 80 or 90% of TFS where the real advantages can be felt. There are some fairly significant infrastructure costs associated with getting to 100%, and we find most organisations don’t want to go that far.

TFS is much more than source control

In fact, if you’re using TFS purely for source control, you’re doing it wrong! You might even be better off using Git or Mercurial.  The best option (of course) is to start using TFS more fully to help you get the best out of your team.

TFS supports your Scrum process beautifully

TFS has some awesome capabilities that allow you to manage and support your entire scrum process. The integration story is compelling; allowing you to tie code changes directly to user stories, produce genuinely useful reports for your managers, and enforce your policies and coding standards allowing you to tick items off your Definition of Done without any effort.

For more information or some reminders of what I spoke about, have a look at the slides on Slideshare – http://www.slideshare.net/damovisa/how-to-be-a-good-tfs-master

Using Generics for Lookup Tables in Entity Framework

Update: “Down the track” has arrived, and I now have an extension to this post that shows a single generic repository that you can use across your application.

I’m working with a client at the moment on a system using legacy database with (wait for it) about 50 lookup tables in their database.  We’re using Entity Framework to access the database, so it’s fairly easy to get the data out of these lookup tables.

However, I really don’t want to write 50 methods to return lists for each of these objects.  Thankfully, the solution is relatively simple – write a generic method to return the appropriate data.

Implementing this wasn’t quite as easy as I thought, but I got there after a bit of experimentation and, I’ll be honest, a fair bit of googling.

To demonstrate, let’s look at an Entity Model with a subset of the AdventureWorks database.

An Adventure Works Entity Model

An Adventure Works Entity Model

In particular, look at the red outlined objects.  These are likely to be referred to frequently throughout the application as simple lookup tables.

We want to write a single generic method that will return an IEnumerable of these objects so we can use them quite simply as lookup tables.

Here’s what I ended up with:

AdventureWorksEntities adventureWorksEntities = new AdventureWorksEntities();
 
public IEnumerable<T> GetLookup<T>() where T : System.Data.Objects.DataClasses.EntityObject
{
    try
    {
        var key = typeof(T).Name;
        // 1. we need the container for the conceptual model
        var container = adventureWorksEntities.MetadataWorkspace.GetEntityContainer(
            adventureWorksEntities.DefaultContainerNameSystem.Data.Metadata.Edm.DataSpace.CSpace);
        // 2. we need the name given to the element set in that conceptual model
        var name = container.BaseEntitySets.Where((s) => s.ElementType.Name.Equals(key)).FirstOrDefault().Name;
        // 3. finally, we can create a basic query for this set
        var query = adventureWorksEntities.CreateQuery<T>("[" + name + "]");
 
        return query.ToList();
    }
    catch (System.Data.EntityException ex)
    {
        throw new ArgumentException("Invalid Entity Type supplied for Lookup", ex);
    }
}

Now we can use the following code to return a set of all items of the appropriate type:

AdventureWorksRepository repository = new AdventureWorksRepository();
var states = repository.GetLookup<StateProvince>();
var addressTypes = repository.GetLookup<AddressType>();
var territories = repository.GetLookup<SalesTerritory>();

This has saved me countless hours of writing boring plumbing code.

Hopefully, some of you are already looking at this thinking, “couldn’t I take this a lot further and provide a set of generic data access methods for everything?”. The answer of course is yes.  I haven’t gone quite that far yet, but I wouldn’t be surprised if it was down the track.

Next Page »