Friday, August 20, 2010

Entity Framework : Hello World

Background

Recently I have been working on lot of code related to database persistence. Writing a data access layer is always a tedious job due to the fact that the relational model of the RDBMS and the domain model of the application might not always be having one to one mapping. We have been using NHibernate as Object Relational Mapping (ORM) tool for our projects for quite sometime. I faced few minor issues around integrating NHibernate with our application. I think NHibernate suffers from the same problem that most of the open source projects face with regards to proper documentation and guideline.

As a result I decided to try something else and Entity Framework seemed to be a good option. The version 4 is out as CTP and there is lot being written about the code-first approach. I had used EF earlier when I was trying the ASP.NET MVC Music Store sample application. On that occasion I blindly followed the steps mentioned in the document and everything was working like magic.

There is lot of talk about the CTP and its capabilities like convention over configuration, support for DataAnnotations for validation purposes etc. I haven’t worked much with the earlier. But things seem to be improving for better in the current CTP version. This post is about what I did to get started with the Entity Framework 4.

Pre-requisites

In order to do code-first development using Entity Framework 4 we need to install the CTP which is available for free download at this link. Note that this is an add on to the Dot Net Framework 4. So we’ll need the Entity Framework 4 to be installed before running the CTP.
I am using the SQL Server CE database which is a lightweight file based instance. You can download the SQL CE 4.0 which is very easy to setup.

My First Entity Framework 4 application

I followed the post by Scott Guthrie on code first development. I didn’t want to go through the elaborate steps of creating an ASP.NET MVC application. So I started off with a good old console application. My domain model consists of two classes. These classes are derived from my current project that I am working at the office. I have a PickTrip class which is a used to store details related to a pick trip. There is a Label class which holds some information related to the customer and orders. The PickTrip class has a collection of labels.

    public class PickTrip

    {

        public int PickTripId { get; set; }

 

        public DateTime DeliveryDate { get; set; }

 

        public string VehicleTripId { get; set; }

 

        public string PickingZone { get; set; }

 

        public int DropNumber { get; set; }

 

        public ICollection<Label> Labels { get; set; }

    }


And the Label class looks like

    public class Label

    {

        public int LabelId { get; set; }

 

        public int PickTripId { get; set; }

 

        public string CustomerName { get; set; }

 

        public int ShortOrderNumber { get; set; }

    }

If you notice carefully in the above code snippets, both the entities have the PickTripId. That is the primary key for PickTrip entity and foreign key for Label entity.


Once I have these two entities I need a way of persisting these to the database and perform CRUD operations on them. We need to have a class which inherits the DbContext class from System.Data.Entity namespace. On this class I expose the properties which are supposed to work with the model classes.

    public class LabelPrinting : DbContext

    {

        public DbSet<PickTrip> PickTrips { get; set; }

 

        public DbSet<Label> Labels { get; set; }

    }

With this much of code we are almost ready to go. The last thing we need is to configure the database. As I mentioned in the beginning, I’ll be using the SQL CE file based database. The code first follows some conventions and if we use the default one then we need a connection string named LabelPrinting in the App.Config. Please note that this should be same as the class name which inherits the DbConext class.

  <connectionStrings>

    <add name="LabelPrinting" connectionString="Data Source = LabelPrinting.sdf" providerName="System.Data.SqlServerCe.4.0"/>

  </connectionStrings>

 

I have also set the provider as SQLServerCe.4.0 and the name of the database is LabelPrinting.sdf.

That is all I need to do to set up the database. If I run the application now and try to add some records to the database, code-first will create the database automatically for me if it does not exist. So lets kick off by inserting a record into the pick trips table.

            ICollection<Label> labels = new List<Label>

                {

                    new Label { LabelId = 1, CustomerName = "Nilesh Gule", ShortOrderNumber = 101 },

                    new Label { LabelId = 2, CustomerName = "Prashanth", ShortOrderNumber = 104 },

                    new Label { LabelId = 3, CustomerName = "Santosh", ShortOrderNumber = 103 },

                    new Label { LabelId = 4, CustomerName = "Amit", ShortOrderNumber = 102 }

                };

 

            PickTrip pickTrip = new PickTrip

                {

                    PickTripId = 3,

                    DeliveryDate = DateTime.Today,

                    DropNumber = 2,

                    Labels = labels,

                    PickingZone = "CH",

                    VehicleTripId = "A23"

                };


So I have created the domain object for pick trip and populated it with a collection of labels. In order to persist this to the database, we need to create an instance of the class which derives from the DbContext class as follows

            labelPrintingContext = new LabelPrinting();

 

            labelPrintingContext.PickTrips.Add(pickTrip);

 

            labelPrintingContext.SaveChanges();


I can use LINQ queries against the persisted data to manipulate it. Here is an example of getting the Count of PickTrips

            int pickTripCount = labelPrintingContext.PickTrips.Count();

 

            Console.WriteLine("Total number of PickTrips in databse are : " + pickTripCount);



Conclusion


Compared to the amount of time I had to spend on setting up the infrastructure of NHibernate and getting started with the first example, EF was very easy. It took me almost a whole day to get the code working with NHibernate. But with Entity Framework I was able to get everything working within less than an hour. I understand from people who have worked with NHibernate that it is a very matured product. But for time being I will continue exploring Entity Framework 4. I liked the simplicity and the approach of the code first method.

I have uploaded the complete working solution at http://dl.dropbox.com/u/1569964/EF-CodeFirstExample.zip. I’ll try to cover up the topics related to entity framework more in depth in future posts.

Until next time Happy Programming :)


Submit Apache Spark job from Command Line to HDInsight cluster

Background This is the 3rd part of the Step by Step guide to run Apache Spark on HDInsight cluster. The first part was about provisioning t...