DotNetStories
Τhis is the second post in a series of posts on how to design and implement an ASP.Net 4.5 Web Forms store that sells posters on line.
Make sure you read the first post in the series.You can find it here.
In all these posts I am going to publish, I will change the
layout. That means I will make changes to the
.master,.css,.aspx files and images. In the final
post I will add the whole solution so you can download
everything.
Have a look at the picture below to see the new slightly changed layout
Now that we have made the necessary changes to the .aspx pages,the master page,the .css files and adding some more images to our site we are ready to move forward and implement the data access layer.
I will use Entity Framework 5.0 in order to create
the data access layer.
Obviously I cannot go into much detail on what EF is and
what it does. I will give a short introduction though.The
.Net framework provides support for
Object Relational Mapping through EF. So EF is a an
ORM tool and it is now the main data access
technology that microsoft works on. I use it quite
extensively in my projects. Through EF we have many things
out of the box provided for us. We have the automatic
generation of SQL code.It
maps relational data to strongly types objects.All
the changes made to the objects in the memory are
persisted in a transactional way back to the data
store.
You can find in this post an example on how to use the Entity Framework to retrieve data from an SQL Server Database using the "Database/Schema First" approach.
In this approach we make all the changes at the database
level and then we update the model with those changes.
In this post you can see an example on how to use the "Model First" approach when working with ASP.Net and the Entity Framework.
For this project I will use the Code First approach
to build the data access layer.
The Code First approach is the more code-centric than the other two (Database First, Model First). Basically we write POCO classes and then we persist to a database using something called DBContext.
Code First relies on DbContext. We create 2,3 classes (e.g Person,Product) with properties and then these classes interact with the DbContext class and we can create a new database based upon our POCOS classes and have tables generated from those classes.We do not have an .edmx file in this approach.By using this approach we can write much easier unit tests.
DbContext is a new context class and is smaller,lightweight wrapper for the main context class which is ObjectContext (Schema First and Model First).
Let's implement our POCO classes
1) Launch Visual Studio and open your solution where your project lives
2) Create a new folder. Name it DAL or any other name
you think it is appropriate.We will place in there our
entity classes
3) Obviously you must include EF in your solution. The good news is that EF is included in any ASP.Net Web Forms Application. If you are not sure whether you have the latest version or not of the EF then just use NuGet.
In my case the EF version is 5.0. Have a look at the picture below
4) We also need to add a reference to the
System.Data.Entity namespace.Select
References from the Solution Explorer and then
choose Add Reference... You have to browse through
the assemblies in the .Net Framework until you locate the
System.Data.Entity and the click OK.
Have a look at the picture below
5) Select the DAL folder, then right-click and then select Add -> New Item.We will add a class file, Poster.cs. Have a look at the picture below
6) Now we need to write the code for the Poster.cs Entity class.Please bear in mind that every instance of the Poster class (an object) will represent a row in the database table and every property in the class declaration will represent a table column. The code follows
public class Poster7) Select the DAL folder, then right-click and then select Add -> New Item.We will add a class file, PosterCategory.cs. The code follows
public class PosterCategory
{
[ScaffoldColumn(false)]
public int
PosterCategoryID { get; set; }
[Required,
StringLength(50), Display(Name = "Category Name")]
public string PosterCategoryName { get; set; }
[Required,StringLength(200),Display(Name = "Category
Description")]
public string
CategoryDescription { get; set; }
public
List<Poster> Posters { get; set; }
}
8) Select the DAL folder, then right-click and then select Add -> New Item.We will add another entity class called PosterContext.cs. This class will inherit from DbContext. Now that we have the entity classes created, we must let the model know.I will have to use the DbSet<T> property.
This class manages the domain classes and provides data
access to the database.Think of it as an orchestrator class.
The code for this class follows
public class PosterContext:DbContext
{
public
DbSet<PosterCategory> PosterCategories { get; set;
}
public DbSet<Poster> Posters { get;
set; }
}
Do not forget to add (using System.Data.Entity;) in the beginning of the
class file.
I would like to talk at this point a little bit about
Code First Data Annotations.With
Data Annotations we can configure our domain-entity
classes so that they can take best advantage of the EF.We
will decorate our entity classes with declarative
attributes.Let me give you an insight on how
EF Code First works.EF Code First at run time,
looks at the entity-domain classes and infers from them the
in-memory data that it needs to interpret the queries and
interact with the database.For example it assumes that any
property named ID represents the key property of the
class.Please have a look at this
post
of mine to find out more about
Data Annotations.
public class PosterInsert :
DropCreateDatabaseIfModelChanges<PosterContext>
{
protected override void
Seed(PosterContext context)
{
var pcategory = new List<PosterCategory>
{
new PosterCategory {
PosterCategoryName =
"Midfielders",CategoryDescription="Posters of active and
past Liverpool Midfielders",
Posters =
new List<Poster>
{
new Poster
{PosterName = "King Kenny", PosterDescription="King Kenny
lifting the European
Cup",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/kenny-dalglish.jpg",PosterPrice=18.95},
new Poster {PosterName = "John Barnes",
PosterDescription="El mago-a true genius in the
midfield",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/john-barnes.jpg",PosterPrice=16.95},
new Poster {PosterName = "Steven Gerrard",
PosterDescription="The
Captain",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/steven-gerrard.jpg",PosterPrice=28.95},
}
},
new PosterCategory {
PosterCategoryName =
"Defenders",CategoryDescription="Posters of active and past
Liverpool Defenders",
Posters = new
List<Poster>
{
new Poster
{PosterName = "Jamie Carragher", PosterDescription="Th
greatest defender in the last ten
years",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/jamie-carragher.jpg",PosterPrice=21.95},
new Poster {PosterName = "Alan Hansen",
PosterDescription="The legendary defender Alan
Hansen",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/alan-hansen.jpg",PosterPrice=13.95},
new Poster {PosterName = "Martin Skrtel",
PosterDescription="The most promising defender playing right
now",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/martin-skrtel.jpg",PosterPrice=19.95},
}
},
new PosterCategory {
PosterCategoryName = "Strikers",CategoryDescription="Posters
of active and past Liverpool Strikers",
Posters = new List<Poster>
{
new Poster
{PosterName = "Ian Rush", PosterDescription="The greatest
striker to wear a Liverpool
shirt",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/ian-rush.jpg",PosterPrice=18.45},
new Poster {PosterName = "Robbie Fowler",
PosterDescription="Robbie, a goal scoring
machine",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/robbie-fowler.jpg",PosterPrice=18.45},
new Poster {PosterName = "Michael Owen",
PosterDescription="The youngest deadliest striker Anfield
has even
known",PosterImgpath="/dotnetstories/building-an-asp-net-4-5-web-forms-application-part-2/images/posters/michael-owen.jpg",PosterPrice=16.95},
}
}
};
pcategory.ForEach(post =>
context.PosterCategories.Add(post));
base.Seed(context);
}
}
In this class I inherit from the DropCreateDatabaseIfModelChanges<PosterContext> class and I will override the default behaviour of that class with my class.
I will ovverride the Seed method with some data.Then I create 3 instances of the PosterCategory entity and 9 entities of the Poster entity.
Then through a simple lambda expression I add the data to the database using this last line of code,
base.Seed(context);
10) Now we need to make one more change.in the Global.asax.cs.
In the Application_Start event handler routine (runs when the application starts) we will add this code
Database.SetInitializer(new PosterInsert());
11) I have also created a Posters folder inside the Images folder and placed in it the 9 images.
12) Build and run your application. Everything should
compile now. Have a look at the picture below to see the
structure of the web application so far.
13) Now we will create a test page to see if the database is
created and populated with values.Add a web form page to the
application.Name it PostersTest.Add a gridview web
server control on the page. Make the page as the
Start Page
In the Page_Load event handling routine type
PosterContext ctx = new PosterContext();
var query = from postcat in ctx.PosterCategories
select postcat.PosterCategoryName;
GridView1.DataSource = query.ToList();
GridView1.DataBind();
Build and run your application. Have a look below to see the result I have got.
It seems to work. The database is created and populated through the magic of EF Code First. Have a look at the web.config for the connection string. In the Solution Explorer look into the App_Data folder.
If you open the Server Explorer and open the connection to
the database (in my case
PostersOnLine.DAL.PosterContext.mdf).I am using
LocalDB, which is anew version of SQL Express.For
more information have a look
here.
Have a look at the picture below.These are the results when
I query the tables.
We can also have a look at the table's definitions.I select
the PosterCategories table in the
Server Explorer window and then choose "Open table
definition".Have a look at the picture below.Please note
that the table's definition is influenced by the data
annotation attributes set in the domain classes.
I will do the same for the Posters table.In this case I also choose to show the T-SQL that is created for the table
Have a look at the picture below.EF Code First does a great
job creating the database objects that reflect the
definition and attributes in the domain classes.
Please make sure you follow all the steps.I will post soon
part 3.
Hope it helps!!!!
Comments have been disabled for this content.