modelBuilder.Configurations.Add and modelBuilder.Entity on OnModelCreating
You have several ways to configure your entities. Below I will show three ways,one using DataAnnotations and two using Fluent Api.
The first variant is using DataAnnotations. You can use attributes(DataAnnotations) to configure your entity classes and properties.DataAnnotations attributes overrides default Code First conventions:
[Table(“BLOGS”)]
public class Blog
{
[Key]
[Column(“BLOGID”)]
public int BlogId { get; set; }
[Column(“NAME”)]
public string Name { get; set; }
[Column(“URL”)]
public string Url { get; set; }
public virtual List<Post> Posts { get; set; }
}
[Table(“POSTS”)]
public class Post
{
[Key]
[Column(“POSTID”)]
public int PostId { get; set; }
[Column(“TEXT”)]
public string Text { get; set; }
public int BlogId { get; set; }
[ForeignKey("BlogId")]
public virtual BaseCard Blog { get; set; }
}
Then, in your context class, you don’t need to override the OnModelCreating method, EF will use the attribute to map your entities and relationship (it will create a 1-to-many relationship between blog and post):
public class BlogContext : DbContext
{
public BlogContext(string name)
: base(name)
{
}
public IDbSet<Blog> Blogs { get; set; }
public IDbSet<Post> Posts { get; set; }
}
Configuring with Data Annotations is fairly simple and it may be just what you’re looking for. But Data Annotations only allow you to access a subset of the possible configurations (though much more than you’ve seen so far). The Fluent API , however, gives you access to even more, so you may prefer it for this reason. With Fluent Api you don’t need to use attributes to map your fields and relationships of your entities classes. There are two ways to use Fluent Api:
1-Mapping the entities (fields and relationships) in the OnModelCreating
method in your context (Your second Aproach):
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().ToTable("BLOGS");
modelBuilder.Entity<Blog>().HasKey(t => t.BlogId);
modelBuilder.Entity<Blog>().Property(t => t.BlogId).HasColumnName("BLOGID");
modelBuilder.Entity<Blog>().Property(t => t.Name).HasColumnName("NAME");
modelBuilder.Entity<Blog>().Property(t => t.Url).HasColumnName("URL");
// The same with post
//mapping one-to-many relationship
modelBuilder.Entity<Post>().HasRequired(c => c.Blog)
.WithMany(s => s.Posts)
.HasForeignKey(c => c.BlogId);
}
2-The second variant using Fluent Api is creating mapping classes (Your First Approach). This way, you configure your Entities in classes that inherit of EntityTypeConfiguration<TEntity>
:
public class BlogMap : EntityTypeConfiguration<Blog>
{
public BlogMap()
{
ToTable("BLOGS");
HasKey(t => t.BlogId);
Property(t => t.BlogId).HasColumnName("BLOGID");
Property(t => t.Name).HasColumnName("NAME");
Property(t => t.Url).HasColumnName("URL");
}
}
public class PostMap : EntityTypeConfiguration<Post>
{
public PostMap()
{
ToTable("POSTS");
HasKey(t => t.PostId);
Property(t => t.Text).HasColumnName("TEXT");
//mapping the relationship
HasRequired(c => c.Blog)
.WithMany(s => s.Posts)
.HasForeignKey(c => c.BlogId);
}
}
Then, to include the mappings in your context you need to add them in the OnModelCreating
method:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new BlogMap());
modelBuilder.Configurations.Add(new PostMap());
}
The best way to add the configurations is at this way:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType
&& type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
This last variant (the first approach) for me is the best due to you don’t have to touch your model classes (adding attributes) to specify what you want and is more flexible if you want to add a new entity or change something.