Pluralization

Unfortunately in the current version of the Entity Framework, which ships in .NET 3.5 SP1, we don't make any attempt to Singularize or Pluralize names when reverse engineering a model from the database.

So if, for example, your database has a table called Orders you will get an EntityType called Orders too, which clearly doesn't make for the most read-able code:

Orders order = new Orders(); //? why not just Order ?

LINQ to SQL does a better job here, because it ships with simple but effective pluralization and singuralization services, that for the most part produces names you would expect.

Unfortunately the lack of a similar feature in the Entity Framework, means that generally the first thing you do after you've reverse engineered a model with the Entity Framework is fix-up all the silly names.

Now from the perspective of someone who delivers plenty of Entity Framework demos, this is quite embarrassing! 

But of course the real problem here is that it is time consuming and error prone for all but the most trivial models.

Solution:

In the next version we have added basic pluralization support. This support only really handles English, and here's why:

  1. Creating language and culture aware services is very hard, and we thought it would be better to spend our time working on the core of the Entity Framework.
  2. These sort of services are very general and as such we think that they belong elsewhere, maybe inside Windows itself?
  3. We have made the PluralizationService class public so you are free to write your own.

Our default English language pluralization is then used whenever you generate a model from a database or visa-versa (see model first) to help produce appropriate names.

And for command line users familiar with EdmGen.exe there is a new /pluralize switch also.

Basic Pluralization Rules:

So how does the Entity Framework use this pluralization service?

Well it calls the service to:

  • Singularize EntityType names
  • Singularize NavigationProperty names that point to 0-1 entities
  • Pluralize EntitySet names
  • Pluralize NavigationProperty names that point to 0-* entities

It turns out that if you do this, you get the model you are looking for most of the time.

The Pluralization APIs:

So far we've talked about default behavior, if however you need more control, for example if you want to specify custom pluralization rules or a create a completely custom service, you have to drop down to the API level.

Everything revolves around a newly added public PluralizationService class that looks something like this:

public abstract class PluralizationService
{
        public static PluralizationService CreateService(CultureInfo culture);

        public abstract string Pluralize(string word);
        public abstract string Singularize(string word);
}

As you can see classes that derive from PluralizationService can singularize and pluralize words.

You can also ask the PluralizationService to create a concrete PluralizationService for you based on Culture (as mentioned previously only "en" based cultures are supported out of the box).

Here is a little code that gets hold of the built-in English Language pluralization services, configures it so "Child" will pluralize to "Children" and then checks that it pluralizes correctly.

PluralizationService pluralizationService = 
PluralizationService.CreateService(
new CultureInfo("en-US"));

ICustomPluralizationMapping mapping =
pluralizationService as ICustomPluralizationMapping;

if (mapping != null) // it shouldn't be but just checking
{
    //Specifying the child pluralizes as children
mapping.Add("Child", "Children");
}

Debug.Assert(pluralizationService.Pluralize("Child") == "Children");

You can use your pluralization service in Model Generation (i.e. the step that produces CSDL and MSL from SSDL) by handing your pluralization service to the EntitySchemaModelGenerator:

//Create an EDM from SSDL generator
EntityModelSchemaGenerator generator =
    new EntityModelSchemaGenerator(
storageModel,
"MyNamespace",
"MyContainer",
pluralizationService);

//Generate CSDL and MSL (in memory)
generator.GenerateMetadata();

The resulting CSDL will have been pluralized/singularized as described in the earlier rules using the provided pluralization service.

See this for more information on the EntityModelSchemaGenerator.

Summary

So as you can see we've added simple pluralization capabilities, akin to those found in LINQ to SQL, that will reduce the amount of work required to create meaningful models.

And to top it off, the solution we've created is easy to customize and public so you can probably use this for other things too!

As always we are very keen to hear what you think.

Alex James
Program Manager
Microsoft

UPDATE:  A number of people have asked whether pluralization can be turned off, because the post doesn't make this clear. The answer is absolutely, pluralization is definitely optional, in Visual Studio this is as simple as checking/unchecking a checkbox in the wizard, and for EDMGen.exe you have to opt-in for pluralization with the  /pluralize commandline switch. 

This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at this post .