Sunday, May 24, 2015

Building a Blog - Pt3.Database Creation, Context and Intializator Classes

In a previous post, I wrote how to set two Models we will use for a start of the Blog project we are building. In case you have missed it you can read it here, but I strongly suggest that you read the very first post of this Small and Simple Blog and see what is this all about.

We need to tell to Entity Framework what database to create and which tables to have. Therefore, we need to create another class that is being called BlogContext. However, it is good to make this class in a separate folder so that we know where are our classes for making Databases are. I created new folder called DataAccessLayer or just shortly DAL. Inside of it create two new classes, one is called BlogContext other one is called BlogInitializer:

Data Access Layer with Context and Intializer Class
Let's first clear out what is one class doing from the other.

The BlogContext, is inheriting another class that is called DbContext class. This is the part of Object Oriented Programing where each class that inherits another class is maintaining the same behavior of that inherited class. The DbContext class is the class that you get when you install Entity Framework for your project, however, to be able to use this class you must specify the use of the Entity Framework in your class. The BlogInitializer class is just there to fill our Database with something on creation. So go to your BlogContext class and add these lines of code:

========================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace BlogProject_Dusan_MVC.Models
{
    public class BlogContext :DbContext
    {
        public BlogContext():base("BlogContext")
        { }

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


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
           
        }
    }
}

===========================================================

1. As you can notice we have to specify to use the package for Entity Framework by adding using System.Data.Entity; and also Conventions that are being used to create relations between tables in our database. This is mostly for the method called OnModelCreating that you can see.

2. Also, we have to change our namespace from BlogProject_Dusan_MVC.DataAccessLayer_DAL_ to BlogProject_Dusan_MVC.Models so that we include the classes from the Model we have previously created. However, you can do this by adding another using statement line in the top of your code.

3. Then we have to inherit the DbContext class by adding next to BlogContext name the :DbContext, that is how you inherit a class.


4. Then we have a constructor of the class that inherits the constructor fo the DbContext class, but the text written inside the base constructor is actually the name of the string that we will add in the Web.Config file of our project.

5. We then have two DbSet properties that are saying to Entity Framework to create a database table with given models that we have done in previous posts.

6. Finally, we have a method or function of our BlogContext class, that is, using conventions, to remove pluralization of our models. If we didn't do this method our tables in the database would be named Posts Blogs. Instead the table names will be Post, Blog. Think of this line of code as something that is personal preference. Some developers think it should be in pluralization and some think it should be not. So you can include or exclude this OnModelCreating method/function.


BlogInitializer class as previously said, it is there to fill our database with some data. The class looks like this:

=============================================================

using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace BlogProject_Dusan_MVC.Models
{
    public class BlogInitializer:System.Data.Entity.DropCreateDatabaseIfModelChanges<BlogContext>
    {
        protected override void Seed(BlogContext context)
        {
         
            var blogs = new List<Blog>
            {

                new Blog{Name="Dushan Blog",BlogID=1}
            };
            blogs.ForEach(s => context.Blogs.Add(s));
            context.SaveChanges();


            var posts = new List<Post>
            {
                new Post{Title="This is a Test Title of the Post 1",Content="This is some text 1", BlogID=1},
                new Post{Title="This is a Test Title of the Post 2",Content="This is some text 2", BlogID=1},
                new Post{Title="This is a Test Title of the Post 3",Content="This is some text 3", BlogID=1},
                new Post{Title="This is a Test Title of the Post 4",Content="This is some text 4", BlogID=1}
            };
            posts.ForEach(s => context.Posts.Add(s));
            context.SaveChanges();


        }
    }
}

======================================================================

1. Again, we see that using System.Data.Entity is being specified for this class so that we get EF classes.

2. Then we see that the class BlogInitilaizer inherits the class from Entity Framework and that class is a Generic class that takes our BlogContext as a type. Again OOP that I won't explain here, I said in previous posts that you should definitely dedicate some time for object oriented programming if you want to understand and create better applications. I can provide you one link about it here: CSharp Generic Classes  for a quick review what is a Generic class.

3. Then we have a method that is called Seed. This method takes the database context object as an input parameter and the code in the method will use that object to add new entities to the database. Our object is BlogContext Class. Remember when I told you a bit of objects when I was talking about the classes? This is that kind of an object. A class is one object! It is also good to know that for each entity type, the code creates a collection of new entities, adds them to the appropriate DbSet property and then saves the changes to the database.

4. We then have two variables that are just reserved as a location in memory and they are a type of List. One variable takes class Blog as a type and we add one object of Blog class with writing "new Blog{}" and inside of it set the given parameters. For the variable posts, it is the same routine, we just add more objects of class Post as we want to have fewer posts to resemble a real post. One thing though is that BlogID is navigational property so we are setting it to number 1 as that is what our BlogID is set to be from blogs variable.

5. After each of this variables, we are going trough the each of elements of the variable, since they are type of List, using ForEach for our variable which is actually LinQ technology, (also something you should read about how it works), where we add each of this element to the BlogContext property.

6. And finally we are saving changes to our BlogContext. You don't need to type after each variable SaveChanges(), but it is good to do so in case you get an error and then you can easily find which one is making you problems.

7. To Summarize what we have just done. We have created two classes. One is BlogContext that creates our database and tables. And another one is BlogInitializier that fills our database with some data.

8. There is one last thing we need to do and that is to set our Web.config file to read this Context and Intializer class. So go to your Web.config file and find the line <appSettings>


If you did then add right above that line this lines of code:

==============================================================
 <connectionStrings>
  <add name="BlogContext" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\dusha_000\Documents\BlogDataBase.mdf;Integrated Security=True;" providerName="System.Data.SqlClient" />
 </connectionStrings>

==============================================================

What you say with this code is that you are adding a ConnectionString to our application. You are adding one that the name of that string connection is "BlogContext" and if you remember you wrote the name in the BlogContext class inside the :base() brackets. Then you specify the ConnectionString.

Now, you should check what is your connectionString. The best way to do that is to go to your Server Explorer tab, or well anywhere where you have the database, click on the Database, not tables, but the Databse, and in the properties you should see the ConnectionString. Like on the picture:

Connection String

Copy that DataSource and write it inside the connectionString="" attribute, because your connection string is different then mine. However, if you leave this attribute blank and just write "Data Source=(LocalDb)\v11.0;Initial Catalog=SomeName;Integrated Security=SSPI;" you don't need to specify the string, but the Entity Framework should make the database with SomeName you have provided. Unfortunately, this didn't work on my PC, I think I have some issue with local accounts and I can't get to connect with this kind of database creation, but creating the database and then copy-pasting its connectionString is doing the trick.

And finally proivedName as you see it in my code.

To tell Entity Framework to use your Context and Intilaizer classes, you need to add an element to the <entityFramework> element in the Web.Config file.

So find the <entityFramework> and add right under that line following:

=============================================================

 <contexts>
      <context type="BlogProject_Dusan_MVC.Models.BlogContext, BlogProject_Dusan_MVC">
        <databaseInitializer type="BlogProject_Dusan_MVC.Models.BlogInitializer, BlogProject_Dusan_MVC" />
      </context>
 </contexts>

============================================================


It is quite straight forward - you add a <context type> element, where your type is the <namespace.class> of your BlogContext, so if you don't know what your namespace is, you can go to your class and copy paste it here and then just add .BlogContext or class name, and then the name of the project.

Inside the <context type> element you are adding a <databaseIntiializer> element, that you do pretty much the same except different name for the class.

So to clear things up, if it is not already clear, we add elements to Web.config file to tell our project to read specific paths that tell our project, where to read things necessary for our project to work properly. In this case Entity Framework is reading what it needs to create in our database and where is that database, by reading our connectionString.

And that would end our Code First Database Creation that had to take 3 parts in doing so. I know it is a dull thing...I mean...it is a lot of following the rules of what you must write to make Entity Framework read the things properly. The funniest part is that you don't even have to do it this way... Meaning in Code First approach.

You can if you are used to use queries in Databases make the tables that way, and then you can create Controllers by reading that database, using Entity Framework. My goal in using this Code First is to show in some way how Models are related to the database.


In the next post, you will finally see how our page for what we have in the database will look like. When you think of saying that this is supposed to be Small and Simple Blog...it doesn't really look like now does it? It will in the next post!