There was interesting discussion about noun pluralization on a mailing list today. One of the fun demos I throw into some talks is the automatic pluralization (taking something singular and making it plural) that's built into the Entity Framework design time tooling. For example, look at the screenshot to the right where a table of type "Goose" is called "Geese" as a set.
Dmitry released a nice "Simple English Noun Pluralizer" a few years back. His code is fun to read and clever for under 400 lines.
In addition to Dmitry's, in .NET 4 (Full Framework, not Client Profile) there's a little known PluralizationService inside of System.Data.Entity.Design that supports this user interface.
At this point there is only support for English and while the class is abstract, there's no proper provider model or factory. Also, personally I think service should be in the Base Class Library (BCL) and should been available as an extension method on string, and I've told them so. That said, it's still pretty cool and useful.
Create a new project in Visual Studio 2010. Right click on the project in the Solution Explorer, and from Properties select ".NET Framework 4" as the Target Framework. Otherwise you won't be able to see System.Data.Entity.Design in the list of .NET Assemblies from the Add Reference dialog. Add a reference, and go to town.
Here's some of the things I tried. I was impressed and confused when it changed Hanselman to Hanselmen. ;)
[Test]
public void AnimalsAreFunWhenPluralized()
{
var p = PluralizationService.CreateService(new CultureInfo("en-US"));
Assert.AreEqual("geese", p.Pluralize("goose"));
Assert.AreEqual("deer", p.Pluralize("deer"));
Assert.AreEqual("sheep", p.Pluralize("sheep"));
Assert.AreEqual("wolves", p.Pluralize("wolf"));
Assert.AreEqual("volcanoes", p.Pluralize("volcano"));
Assert.AreEqual("aircraft", p.Pluralize("aircraft"));
Assert.AreEqual("alumnae", p.Pluralize("alumna"));
Assert.AreEqual("alumni", p.Pluralize("alumnus"));
Assert.AreEqual("houses", p.Pluralize("house"));
Assert.AreEqual("fungi", p.Pluralize("fungus"));
Assert.AreEqual("Hanselmen", p.Pluralize("Hanselman"));
Assert.AreEqual("Hanselman", p.Singularize("Hanselmen"));
}
As I mentioned, If you wanted, you could derive from PluralizationService and create a Spanish or whatever-you-like service and plug it into the Entity Framework. Dmitry could even swap out the included service and broker calls to his own.
Note that this class was really just meant to be used from the EF Tooling, but I'd like to put gentle pressure on the Powers That Be (if this is useful) to put a little more work into it, make it a core thing, and make it work in more languages.
UPDATED: An interesting point from Jon Galloway. If you are using Entity Framework Code First, you can effectively disable the Pluralization Convention for Table Names by, ahem, removing the PluralizingTableNameConvention. Funny how that works, eh?
namespace MvcMusicStore.Models
{
public class MusicStoreEntities : DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Genre> Genres { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Cart> Carts { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Cool.
© 2011 Scott Hanselman. All rights reserved.