How to get the EDMX metadata from a Code First model (and why you need it)
Entity Framework provides a very good experience with its Code First development model. In it you can define classes and use them as POCO entities (Plain Old CLR Objects). For example, consider the following model:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
[MaxLength(200)]
public string Title { get; set; }
public int LikeCount { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
In terms of usability it's a great way to go since the code is self-explanatory and can be highly customized via the Fluent API. Now, you might be asking yourself: what happened with the EDMX file? Well, you don’t really see it but it still exists.
The way Entity Framework Code First works is by analyzing your assemblies for all the types related to your model and enumerating into a set of “discovered types”. Once EF knows about these types, it explores them looking for special attributes such as [Key], [MaxLength] and [Index] to know more about the model. Finally, it applies a set of conventions that allow it to discover information that’s not explicitly set. One such convention is the discovery of keys by which field PostId is discovered as the key to the Post entity. There’s a number of these conventions and it’s important that you understand them before using Code First.
The resulting fully-loaded model description is stored in memory using the EDM format. Effectively, Code First reverse-engineers an EDMX out of the POCOs, attributes and fluent API calls. From here on, Entity Framework doesn’t care whether you created the model Code First or Model First, it behaves the same. It goes on and generates the views, validates the model and sets up all the metadata to be ready to serve its purpose.
As you might imagine the process of reverse engineering the EDMX out of the Code First model is costly. It’s only paid for once on the startup of your first context, but it may represent a performance annoyance for your application. There’s a way to speed your start up though: use an EDMX in your project.
For this, you’ll want to obtain the EDMX data from your Code First context by calling:
EdmxWriter.WriteEdmx(context, new XmlTextWriter(new StreamWriter("MyModel.edmx")));
Call it in your context instance and you’ll get an EDMX file with all the data you require. Add the EDMX to your project and modify your connection string accordingly to make use of the EDMX data.
Large models will benefit the most. I’ve noticed reductions in the hundreds of milliseconds just for the EDMX generation part of the code.