modelBuilder.Configurations.Add and modelBuilder.Entity on OnModelCreating

c# entity-framework-6

Question

I have just started working on entity framework code first approach, I have written two approaches below and both are working fine.

Please let me know what are the core concepts behind both these approaches and what should follow?

Approach 1 : Using EntityTypeConfiguration

public class BlogsMap : EntityTypeConfiguration<Blog>
    {
        public BlogsMap(string schema)
        {
            ToTable("BLOG");
            HasKey(t => t.BlogId);
            Property(t => t.BlogId).HasColumnName("BLOGID");
            Property(t => t.Name).HasColumnName("NAME");
            Property(t => t.Url).HasColumnName("URL");
        }

    }


public class BlogContext : DbContext
    {
        public BlogContext(string name)
            : base(name)
        {
        }

        public IDbSet<Blog> BLOG { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
           modelBuilder.Configurations.Add(new BlogMap(string.Empty));
        }
    }

Approach 2 :

public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
        public virtual List<Post> Posts { get; set; }
    }


    public class BloggingContext : DbContext
    {     

        public DbSet<Blog> Blogs { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Blog>();

        }
    }

Please provide me concept/blogs on entity,since i have just started.

1
12
1/2/2015 10:29:21 PM

Accepted Answer

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.

36
1/2/2015 9:44:48 PM

Popular Answer

        string nspace = "CompanyAdministration.data.Models";
        var q = from t in Assembly.GetExecutingAssembly().GetTypes()
                where t.IsClass && t.Namespace == nspace && t.Name[0] != '<' && t.Name.Substring(0, 2) != "BOX" && t.Name != "CAContext"
                select t;
        foreach (Type t in q)
        {
                try
                {
                    MethodInfo method = modelBuilder.GetType().GetMethod("Entity");

                    method = method.MakeGenericMethod(new Type[] { t });

                    method.Invoke(modelBuilder, null);
                }
                catch
                {
                }
        }

        base.OnModelCreating(modelBuilder);


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow