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.
After installing the tool and creating a new class library project, I reverse engineered the following tiny simple database:
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.
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.