modelBuilder.Configurations.Add and modelBuilder.Entity on OnModelCreating

c# entity-framework-6

Question

I've only recently begun working on the entity foundation code first method, but both of the ways I've listed below are already performing well.

Please explain the fundamental ideas underlying both of these approaches and what steps should come next.

Method 1:Making use of 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));
        }
    }

Method 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 give me any concepts or blogs about entities as I'm just getting started.

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

Accepted Answer

Your entities can be configured in a variety of ways. Three approaches are demonstrated below, two of which make use of Fluent API and one of DataAnnotations.

DataAnnotations are used in the first variation. You can set up your entity classes and properties using attributes(DataAnnotations). The default Code First conventions are overridden by DataAnnotations attributes:

[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, since EF will use the property to map your entities and relationships (creating a 1-to-many relationship between blog and post), you don't need to override the OnModelCreating method in your context class:

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

    public IDbSet<Blog> Blogs { get; set; }
    public IDbSet<Post> Posts { get; set; }
}  

Data Annotations configuration is quite easy and can be exactly what you need. However, Data Annotations only give you access to a portion of the configurations that are available (though there are many more than what you've seen so far). However, you get access to even more with the Flowing API, so you could prefer it for this reason. You can map your entity classes' fields and relationships without using attributes when using Fluent Api. Use Fluent Api in one of two ways:

1 mapping the entities in the database (fields and relationships)OnModelCreating strategy appropriate to your situation (second approach):

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 creation of mapping classes is the second Fluent API version (Your First Approach). By doing so, you can set up your Entities in classes that derive fromEntityTypeConfiguration<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);

    }
}

Afterward, you must incorporate the mappings in your context by including them in theOnModelCreating method:

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

The following is the best method for adding configurations:

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);  
}

Because you don't need to modify your model classes (by adding attributes to express what you want) and it's more adaptable if you want to add a new entity or change something, I think the last variant (the first way) is the best.

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