Quick Look at Reverse Engineer DB into Code First Classes

The Entity Framework team blogged about the EF Power Tools CTP1 today. One of the intriguing features is the ability to reverse engineer an existing database into a set of code first classes.

 

I put it to a *very* quick test since it’s way past my bedtime. Smile

After installing the tool and creating a new class library project, I reverse engineered the following tiny simple database:

image

The tool created a bunch of classes grouped into an Entities folder (from tables and views in my db), a set of fluent api mappings grouped into a Mapping folder and a context class. It also added the EntityFramework.dll for EF 4.1 and System.Data.Entity to the project.

image

 

A quick look at one of the Customer.cs class:

using System;
using System.Collections.Generic;

namespace TestEFPowerToolsCTP1.Entities
{
    public class Customer
    {
        public Customer()
        {
            this.Orders = new List<Order>();
        }

        public int CustomerID { get; set; }
        public string Title { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public string Suffix { get; set; }
        public string CompanyName { get; set; }
        public string SalesPerson { get; set; }
        public string EmailAddress { get; set; }
        public string Phone { get; set; }
        public System.DateTime ModifiedDate { get; set; }
        public byte[] TimeStamp { get; set; }
        public virtual ICollection<Order> Orders { get; set; }
    }
}

The Customer mapping file:

using System;
using System.Data.Entity.ModelConfiguration;
using System.Data.Common;
using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using TestEFPowerToolsCTP1.Entities;

namespace TestEFPowerToolsCTP1.Mapping
{
    public class CustomerMap : EntityTypeConfiguration<Customer>
    {
        public CustomerMap()
        {
            // Primary Key
            this.HasKey(t => t.CustomerID);

            // Properties
            this.Property(t => t.Title)
                .HasMaxLength(8);
                
            this.Property(t => t.FirstName)
                .IsRequired()
                .HasMaxLength(50);
                
            this.Property(t => t.MiddleName)
                .HasMaxLength(50);
                
            this.Property(t => t.LastName)
                .IsRequired()
                .HasMaxLength(50);
                
            this.Property(t => t.Suffix)
                .HasMaxLength(10);
                
            this.Property(t => t.CompanyName)
                .HasMaxLength(128);
                
            this.Property(t => t.SalesPerson)
                .HasMaxLength(256);
                
            this.Property(t => t.EmailAddress)
                .HasMaxLength(50);
                
            this.Property(t => t.Phone)
                .HasMaxLength(25);
                
            this.Property(t => t.TimeStamp)
                .IsRequired()
                .IsFixedLength()
                .HasMaxLength(8);
                
            // Table & Column Mappings
            this.ToTable("Customers");
            this.Property(t => t.CustomerID).HasColumnName("CustomerID");
            this.Property(t => t.Title).HasColumnName("Title");
            this.Property(t => t.FirstName).HasColumnName("FirstName");
            this.Property(t => t.MiddleName).HasColumnName("MiddleName");
            this.Property(t => t.LastName).HasColumnName("LastName");
            this.Property(t => t.Suffix).HasColumnName("Suffix");
            this.Property(t => t.CompanyName).HasColumnName("CompanyName");
            this.Property(t => t.SalesPerson).HasColumnName("SalesPerson");
            this.Property(t => t.EmailAddress).HasColumnName("EmailAddress");
            this.Property(t => t.Phone).HasColumnName("Phone");
            this.Property(t => t.ModifiedDate).HasColumnName("ModifiedDate");
            this.Property(t => t.TimeStamp).HasColumnName("TimeStamp");
        }
    }
}

and the context:

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using TestEFPowerToolsCTP1.Entities;
using TestEFPowerToolsCTP1.Mapping;

namespace TestEFPowerToolsCTP1
{
    public class CustomersContext : DbContext
    {
        static CustomersContext()
        { 
            Database.SetInitializer<CustomersContext>(null);
        }

        public DbSet<Customer> Customers { get; set; }
        public DbSet<LineItem> LineItems { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<Product> Products { get; set; }
        public DbSet<sysdiagram> sysdiagrams { get; set; }
        public DbSet<custview> custviews { get; set; }
        public DbSet<vSalesOrderDetail> vSalesOrderDetails { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new LineItemMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new sysdiagramMap());
            modelBuilder.Configurations.Add(new custviewMap());
            modelBuilder.Configurations.Add(new vSalesOrderDetailMap());
        }
    }
}

Very nice!

One of the suggestions in the comments on the team blog post is to be able to select which tables/views get reverse engineered.

  Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!  

7 thoughts on “Quick Look at Reverse Engineer DB into Code First Classes

  1. Just bought your 2nd ed. book (excellent!). Am just learning EF, so a definite noob.

    EF looks *really* nice, but one glaring omission I just found is the designer has no support for UNIQUE? That surprised me.

    Are there workarounds?

    Also, would really rather use one of the UML modellers like EA or Visual Paradigm to model and generate DDL & persistance-ignorant domain classes. Any experience with this workflow of using 3rd party modelling to generate DDL, and then VS2010 "update from DB"?

    BTW, I asked a similar question a couple weeks ago on your other blog FYI. I havent found the "sweet spot" on this yet… 🙂

  2. @Joe – you can use unique foreign keys with an independent association but not with FK associations. You should be able to find out how this works with a web search (sorry I’m at a conference).

    re your other q – nope, no experience whatsover. Is it even possible? DevArt’s tool might do this. Also check Huagati.com tools

  3. Also wondering why it generated:

    public System.DateTime ModifiedDate { get; set; }

    Instead of:

    public DateTime ModifiedDate { get; set; }

  4. Very slick. Per Joe’s question–I feel like using EA to to model and generate DDL & persistence-ignorant domain classes is kind of a round-about way, compared to above.

  5. Its really great but i think these validation rules shouldn’t be in mapping class because we cant reuse them to generate MVC client validators.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.