Tuesday, February 25, 2014

Intro to Entity Framework Code-First

Each Monday, one member of our development team is scheduled to give a Brown Bag presentation on a technology related topic.  I was scheduled for an F# presentation in a couple weeks, but recently did some research on Entity Framework Code-First.  I was impressed with the Code-First approach as it did not have all of the overhead of an edmx and just seemed a lot cleaner.  So, instead of stumbling through an F# presentation in a couple weeks, I decided to just give a quick demo of Entity Framework Code-First today and also put it out as a blog.

I created a video that basically follows the steps below.  This will allow you to see me perform the steps just in case something is not clear in the text steps.  The audio of the video recording is not very good, but you should be able to follow along.  I will re-record it in the future, but didn't want this to stop the post from going out.  Also, please remember to change the quality to 720p by selecting Settings -> Quality -> 720p HD.







The first 17 steps are related to creating the supporting unit test project as well as a class library that the test project will call and that project makes the calls to the class library project where the Entity Framework code is located.  I encourage anyone reading this to follow all steps, but wanted to explain how this post is structured.  I will also use some ReSharper commands throughout this post, so if you do not have ReSharper, you may need to do a few of the steps manually.

1.   The first step that I always do and if you read any of my previous posts, you know that I always create a blank solution.  In this case, the blank solution name is BrownBag.  If you need a refresher on how to do this, see my post on creating a Blank Solution.

2.   Next, because we are TDD developers, we create our unit test project named BrownBag.Tests.  We do this by right clicking on the BrownBag solution and selecting Add -> New Project.  Select the Test project and name it BrownBag.Tests as seen below.
























3.   The first test method we are going to create is going to be named the following:

    public void AddUser_ValidUserName_ReturnsUserId  

4.   Inside the test method under Arrange, type the following code:

      var user = new User();

5.   As you can see, User does not exist yet, so we have to create it, but where is it going to go?  For the purpose of this demo, we are going to create a new Class Library project named BrownBag.BL and add our code there.

6.   After the new project is created, rename the Class1.cs file to User.cs

7.  Go back to your test project and place your cursor over User() and then select Alt + Enter.  You will see an option for Reference 'BrownBag.BL and use BrownBag.BL.User.  This will add the correct using directive and add the reference as well.
























8.  You are now ready to "Act" within your test method by typing the following code:

     var userId = user.Create(userDTO);

9.   As you can see we will need to add the "Create" method within our User class that is defined in the       BrownBag.BL Class Library project.  To accomplish this easily, put your cursor over the Create method call and select Alt + Enter.  This will give you the option to create the method User.Create.










10.  You will see that the Create method is created for you.  Our test will expect the return value to be an int, so we need to change object to int and replace the NotImplementedException with return 0; 













11.   If we go back to our test class, we will see that the passed in parameter is not defined.  In our example, we want to create a DTO that will be passed in to the Create method.  To do this, you might have guessed, you need to put your mouse over userDTO and select Alt + Enter.  This will create a local variable within our Act section, so we need to move it to the Arrange section.  To do this quickly and since we are on the line we want to move, we select Ctrl + X, then move our cursor to after the creation of user and then select Ctrl + V.






















12.  Replace the code that we moved with the following:

     var userDTO = new UserDTO
     {
         UserName = "UnitTest_" + Guid.NewGuid().ToString()
     };  

13.  Click UserDTO, then Alt + Enter, then Create Class UserDTO.  This will create the DTO class that will be used to pass in to the Create method.












14.  Click UserName, then Alt + Enter, then Create Property UserName.  This created the property UserName without having to write any code.










15.  Move cursor to the right of UserDTO and select F6, then select Move To Folder.  Change the target folder to the BrownBag.BL.  We do this to move the created class to a new file in a better location.























16.  Within the Create method of the User class, change the passed in userDTO type from object to UserDTO.

17.  We are now ready to create our Assert by entering the following code into our Assert section in our test method.

       Assert.IsTrue(userId > 0);

Now that we have our test complete, we can get into our Entity Framework specific code!

18.  Add a new Class library project to our solution that will be used for our Datalayer and name it BrownBag.DL.  Once the project is created, delete Class1.cs.

19.  In order to use the entity framework, you must add a reference to the EntityFramework assembly.  We are going to use the Package Manager Console and install a NuGet package.  To open the Package Manager Console, go to Tools -> Library Package Manager -> Package Manager Console.  














Once there, change the default project to BrownBag.DL, 





and then type in the following:

PM> Install-Package EntityFramework

If everything was successful, you will see the assemblies added as seen below:










Do the same steps for BrownBag.BL and BrownBag.Tests projects by changing the Default project and running the same command.

20.  Add a class to your BrownBag.DL named BrownBagContext.cs and then add a constructor like the following and make sure your class inherits from DbContext













21.  Add the following connection strings section to the App.config in the DL and Tests project.  In the below example, please replace the Data Source with your values and also make sure a blank database with the catalog name is created in your SQL Server instance.  We create the Database here, but the columns will be created using Code-First.

<connectionStrings>
<add name="BrownBagContext" connectionString="Data Source=XXXX\SQLEXPRESS;initial catalog=BrownBag;persist security info=True;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>

22.  Add the following property to your BrownBagContext.cs class

       public DbSet<User> Users { get; set; }

23.   Put your cursor over User, select Alt + Enter,  and select Create class 'User'.  This will create the class that will be used to create the columns in our database.

















24.  Put your cursor next to User and select F6, and then Move to Another File.  This will put the class in a new file.










25.  Add the following properties to your new class:

     [Key]
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public int UserId { get; set; }
     [StringLength(50)]
     public string UserName { get; set; }

26.   Add the two using directives

     using System.ComponentModel.DataAnnotations;
     using System.ComponentModel.DataAnnotations.Schema;

27.   Add a reference and using directive to BrownBag.DL in BrownBag.BL.

28.   Add the following code to the Create method in the User Class in the BL

       using (var dbContext = new BrownBag.DL.BrownBagContext())
     {
        var user = new BrownBag.DL.User
        {
           UserName = userDTO.UserName
        };

        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        return user.UserId;
     }

29.  Finally, we can use migrations to create the table and columns in our database.  Go back to the Package Manager Console and type Enable-Migrations.  You will see a Migrations folder created within your project with a class named Configuration.

30.  When the Enable-Migrations command is complete and successful, type Add-Migration UserTableCreation.  The Add-Migration command will create a class that will be executed to create the table and columns in the database.  The UserTableCreation is a label that you make up to identify the migration.

31.  You will now see that the Migrations folder contains the C# code that we explained above.  










At this point the table is not created yet.  To create the table in your database, type the following in the Package Manager Console:

PM> Update-Database

32.  If all goes well, you should see the table is created along with the fields you specified.













33.  Now, go back to your unit test, set a breakpoint and step through your code.  You should get a userId back which should make your test pass!  You should also go to the database and verify that a record was created.












That is my quick intro to Entity Framework Code-First.  There are many posts online that explain some of this, but I think this pulls a lot together that may be assumed from other sites.  I hope you enjoyed and learned something along the way.  If you go through the steps and something does not make sense, please take a look at the video.  As I said above, the audio quality is not very good, but you should be able to follow along.

peace yo!