38

I am just taking a crack at entity framework code first. Following their naming convention, we now have to name our tables plural to not have to intervene with the tool. I know the mappings can be over ridden. My question is, after years of following the singular naming convention are we back to using plural names?

Also, I was wondering why the new examples were using Northwind instead of Adventure Works. I'm thinking the reason is because AW uses singular naming and they wouldn't be able to show off the no code features

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Paul Speranza
  • 2,302
  • 8
  • 26
  • 43

3 Answers3

73

The RTM version of Code First will fully support a cool feature called Pluggable Conventions where you can add or replace the default conventions such as the one you mentioned.

Fortunately, what you are looking for is already included in CTP5. You can switch off the pluralizing table names convention with removing PluralizingTableNameConvention convention. This is all the code you need to write for this matter:

using System.Data.Entity.ModelConfiguration.Conventions.Edm.Db;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{    
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}


About your secound questions, the reason you more see Northwind database than Adventure Works is just because AW is a huge and Northwind is a fairly small database hence make it a better fit for samples and Walkthroughs. That said, you still need to write some code to work with Northwind database in Code First.

Morteza Manavi
  • 33,026
  • 6
  • 100
  • 83
  • I knew I could override the conventions with comething like modelBuilder.Entity().ToTable("ApplicationUser");. I am just wondering if singular naming of tables is still the "in" thing. – Paul Speranza Dec 13 '10 at 17:01
  • What you said is using fluent API and that's *NOT* what I meant by *switching off conventions*. We can just turn off a convention *entirely* for our application by *Pluggable Conventions*. I updated my answer to clarify. – Morteza Manavi Dec 13 '10 at 17:49
  • 2
    Thank you for the clarification and example. I feel like I am drinking from a firehose between EF CodeFirst and MVC 3! – Paul Speranza Dec 13 '10 at 17:56
  • 1
    No problem and Yep, that's always the case for the folks who are walking on the bleeding edge of technology :) BTW, I'm all with you in this one, I don't like pluralizing table names as well. – Morteza Manavi Dec 13 '10 at 18:49
  • Aren't pluralized table names a standard naming convention according to Microsoft? – Jason Jan 31 '11 at 22:00
  • No. For example, if you take a look at `AdventureWorks` as Microsoft's SQL Server sample database, you will see that all the table names are singular. – Morteza Manavi Jan 31 '11 at 22:07
  • I wonder why nobody mentions where this code goes. It's inside your `DbContext` class. – Andrew Jan 18 '21 at 16:53
3

here is one extract of the code I'm using and is working 100%. Try copy and paste and try it, it must create singular name table names. I'm using EF4.1 and CE4.0

POCO class

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace CloudOne.Models
{
    public class Brand
    {
        public int BrandID { get; set; }
        [MaxLength(25)]
        [Required]
        public string BrandName { get; set; }
        [MaxLength(1000)]
        public string BrandDescription { get; set; }
        public int SortOrder { get; set; }
        //SEO
        [MaxLength(70)]
        public string PageTitle { get; set; }
        [MaxLength(100)]
        public string MetaDescription { get; set; }
        [MaxLength(150)]
        public string MetaKeywords { get; set; }
        [MaxLength(56)] //50 + "-" + 99,000
        public string Slug { get; set; }
    }
}

Data Context

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace CloudOne.Models
{
    public class SiteDataContext: DbContext
    {
        public DbSet<Brand> Brands { get; set; }

        // Twist our database
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }
}

The Seed initializer

public class SiteDataContextInitializer: DropCreateDatabaseIfModelChanges<SiteDataContext>
    {
        protected override void Seed(SiteDataContext context)
        {
            var brands = new List<Brand>()
            {
                new Brand { BrandName = "Brand 1", Slug = "brand-1" },
                new Brand { BrandName = "Brand 2", Slug = "brand-2" }
            };

            brands.ForEach(d => context.Brands.Add(d));

            base.Seed(context);
        }
    }

Try to copy and paste this code, then write some code to trigger the database creation (i.e. try to fetch the records and show in the index page).

Nestor
  • 1,969
  • 4
  • 25
  • 30
1

I have tried and is like EF4 CTP5 is totally ignoring it. What can be wrong?

using section:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions.Edm;

DbContext:

public class SiteDataContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<BlogFeedback> BlogFeedbacks { get; set; }
        public DbSet<BlogCategoryList> BlogCategoryLists { get; set; }
        public DbSet<BlogCategory> BlogCategories { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }

POCO classes

public class Blog
    {...}
public class BlogFeedback
    {...}
public class BlogCategoryList
    {...}
public class BlogCategory
    {...}

Tables generated:

Blogs
BlogCategories
BlogCategoryLists
BlogFeedbacks

What I need:

Blog
BlogCategory
BlogCategoryList
BlogFeedback

One thing may be different is I split my solution into two projects Core and Web. Core has Models, Services and all Code First. Web has only Controllers and Views and a reference to Core. The SetInitializer().Seed() is inside a function in Core, and in Web global.asax the Core.SetInitializer is called, so keep all CTP5 functions inside Core. Database is being recreated ok, data is filled ok, just the convention keeps PLURAL TABLE NAMES, ignoring the modelBuilder override

Nestor
  • 1,969
  • 4
  • 25
  • 30
  • I've got exactly the same issue. Have you found a solution? – 0xbadf00d May 16 '11 at 09:22
  • 3
    Yeah, I misspelled and used wrong convention constant. Make sure you are using "PluralizingTableNameConvention" instead of "PluralizingEntitySetNameConvention" – Nestor May 19 '11 at 13:23
  • Too bad, I'm already using the right one. I've no idea why it's ignored. – 0xbadf00d May 20 '11 at 05:02
  • What EF version you are using? In this example I was using EF4.0 + CTP5, now I'm using EF4.1, it changes a little but basically is the same. Check if you are including all libraries in the using section, and tell me the EF version so I may be able to help you. – Nestor May 23 '11 at 01:00
  • @FrEEzE2046, I posted a working sample code here below, please check it, hope it can solve your problem. – Nestor May 23 '11 at 09:16