Fluent API vs Data Annotations Working with Configuration – Part 2


I hope, you have already learned very basic on Fluent API and Data Annotations in Part 1. And hope you have learned how to work with code first using Author and Book classes on previous article. We have decided to change the class name from Author to Publisher as Publisher and Book is more appropriate for One to Many relationship. Ok let’s start, Code First allows you to override its conventions by applying additional configurations. You can choose either attribute based data annotation or strongly typed Fluent API for those configurations. You have seen how how to override the OnModelCreating method. The DbModelBuilder that is provided to the OnModelCreating method is the class for adding configurations.

public DbSet Publishers { get; set; }
public DbSet Books { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
            modelBuilder.Entity<Publisher>()
                .Property(n => n.PublisherName).IsRequired();
            modelBuilder.Entity<Publisher>()
                .Property(d => d.Description).HasMaxLength(500);
            modelBuilder.Entity<Publisher>()
                .Property(p => p.Photo).HasColumnType("image");
            modelBuilder.Entity<Book>()
                .Property(n => n.BookName).IsRequired();
            modelBuilder.Entity<Book>()
              .Property(n => n.BookName).HasMaxLength(200);
}

So you know how to work with Required, Column Type check, Max Length. How to configure properties of a class. You can also configure the class itself. You can also specify that which database table it should map to:

modelBuilder.Entity<Publisher> ().ToTable(“Your_Desired_Table_Name);

It is possible to use both Data Annotations and Fluent API. If you use both together your code will become inconsistent. It is always advised that try to keep your code consistent. So use any one, either Data Annotations Or Fluent API.

Now, if you need lot of configuration to perform, the OnModelCreating method mighty quickly become overwhelmed with code. You can group configuration by entity within individual EntityTypeConfiguration classes and then call them.  Let us separate Book and Publisher. Add two classes: 1) BookConfiguration 2) PublisherConfiguration. Your classes should look like the following:

 public class BookConfiguration : EntityTypeConfiguration<Book>
    {
        public BookConfiguration()
        {
            Property(n => n.BookName).IsRequired().HasMaxLength(200);
        }
    }
 public class PublisherConfiguration : EntityTypeConfiguration<Publisher>
    {
        public PublisherConfiguration()
        {
            Property(n => n.PublisherName).IsRequired();
            Property(d => d.Description).HasMaxLength(500);
            Property(p => p.Photo).HasColumnType("image");
        }
    }

Calling modelBuilder.Entity<Book>() will actually create an EntityTypeConfiguration<Book> and return it to you, so whichever approach you choose, you are accessing the same API.

Now change your OnModelCreating method that consumes those two classes  you created earlier. Your code should look like the following:

  public class LibraryDB:DbContext
    {
        public DbSet<Publisher> Publishers { get; set; }  
        public DbSet<Book> Books { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new BookConfiguration());
            modelBuilder.Configurations.Add(new PublisherConfiguration());
        }
    }

Now you will learn how to recreate the database when the model change or to match the model to database. Before that, make sure you have installed EF latest version properly. You can use NuGet package manager for that. The Entity Framework can create, update, drop databases when application runs. The Entity Framework recommends to use “Database Migrations” as a prevention for loosing old records. But for production environment you always need to generate some test data. Entity Framework has “Seed” Method that allows you to seed some dummy data in the database. Lets have a look how to do that:

There are two methods for achieving your purpose , write any one of the following lines within Application_Start inside “Global.asax.cs” file. There is another good way to do that with dummy data. Add a new class named “DBInitializer” inherits from “DropCreateDatabaseIfModelChanges<LibraryDB>“.

   protected override void Seed(LibraryDB context)
            {
                //base.Seed(context);
                context.Publishers.Add(new Publisher
                {
                    PublisherName="O'Reilly",
                    Description="NA"
                });
                context.Publishers.Add(new Publisher
                {
                    PublisherName = "McGraw.Hill",
                    Description = "NA"

                });
               context.SaveChanges();
            }

Hope you all enjoyed. Have fun 🙂

8 thoughts on “Fluent API vs Data Annotations Working with Configuration – Part 2

  1. Hello there, just became alerted to your blog through Google, and found that it’s really informative. I will be grateful if you continue this in future. Numerous people will be benefited from your writing. Cheers!

  2. I just want to tell you that I am just beginner to blogging and site-building and absolutely loved you’re website. Probably I’m want to bookmark your site . You actually come with great writings. Thank you for sharing with us your blog.

  3. Hey! This post couldn’t be written any better! Reading through this post reminds me of my previous room mate! He always kept talking about this. I will forward this post to him. Fairly certain he will have a good read. Many thanks for sharing!

Leave a comment