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.
Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!
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… 🙂
@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
Was looking forward to this feature. Impressive.
Also wondering why it generated:
public System.DateTime ModifiedDate { get; set; }
Instead of:
public DateTime ModifiedDate { get; set; }
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.
EF Power Tools is a good and useful tool, but there is a problem with usage of existing DbContext with connection string from the *.config file.
Code-First fluent mapping can also be generated from database for Oracle, MySQL, PostgreSQL, and SQLite by Devart Entity Developer: http://www.devart.com/…/using-entity-fr .
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.