Showing posts with label DbContext. Show all posts
Showing posts with label DbContext. Show all posts

Tuesday, June 3, 2014

Step By Step How to create a Generic Data Repository in ASP.NET MVC 4

         By Carmel Schvartzman

In this tutorial we'll learn how to create a Generic Data Repository in ASP.NET MVC 4. This MVC C# code example can be downloaded from the following GitHub repository:
https://github.com/CarmelSoftware/Generic-Data-Repository-for-ASP.NET-MVC
A Wiki page is here:
https://github.com/CarmelSoftware/Generic-Data-Repository-for-ASP.NET-MVC/wiki
A Data Repository is a class designed to implement the Repository Pattern. This software pattern was designed in order to access, cache in memory and persist in the database the application data.  Thus the repository will support all CRUD operations (Create Retrieve Update Delete) enhancing a clear separation between data domain and database.
There exist Repository implementations with the use of data caching. The caching only stands to avoid unnecessary round trips to the SQL server. But when scalability of the sites is on the stage, may be we don't want to choke our web server's memory. Then, caching is not only redundant, but also dangerous as a waste of the web server resources.
In this tutorial we'll add GENERIC Repository functionality (no caching) to a new ASP.NET MVC 4 app.
That means, our Repository will offer all CRUD functionality, using the same GENERIC methods for all classes.
In successive tutorials, we'll use this Generic Data Repository to build MVC Applications as the following :



Let's say we have an MVC internet application with an Entity Data Model mapped to an SQL server database. This EDM maps just two entities: Blog and Comment:
Generic Data Repository in ASP.NET MVC 4

We'll develop a GENERIC Data Repository which will support ALL model entities in our application.
First, create a new class in the Model folder, name it "Repository", and type the following EDM context instantiation:

Data Repository in ASP.NET MVC 4

 public class DataRepository : IDisposable
    {
        #region Context
        private BlogEntities _Context;
        public BlogEntities Context
        {
            get
            {
                if (_Context == null)
                {
                    _Context = new BlogEntities();
                }
                return _Context;
            }

        }
        #endregion
Next, create the SAVE method, as follows:
Generic Repository in ASP.NET MVC 4

 public bool Save(object target, int RecordsNumber)
        {
            try
            {
                return Context.SaveChanges() == RecordsNumber;
            }
            catch (OptimisticConcurrencyException)
            {
                ObjectContext ctx = ((IObjectContextAdapter)Context).ObjectContext;
                ctx.Refresh(RefreshMode.ClientWins, target);
                return Context.SaveChanges() == RecordsNumber;
            }
        }

        public void Dispose()
        {
            if (Context != null)
            {
                Context.Dispose();
                GC.Collect();
            }
        }
As you see, we have a response in case of a concurrency exception. Optimistic Concurrency Exception means, we are optimistic in supposing that the current record being updated by us, is not being changed by anybody else. But, if at the moment we SAVE the record, the Entity Framework realize it has been changed in the meantime by somebody else, it will not allow us to save, but will throw an OptimisticConcurrencyException instead. What we do here, is REFRESHING the entity (getting the updated record) , state that CLIENTWINS over the data store (meaning that OUR changes override the record from database), and then SAVE it again.
Notice that we CAST the DbContext in an ObjectContext, in order to REFRESH the data.

Now let's code the complete C.R.U.D. (Create Retrieve Update Delete) operations, in a generic way:
Generic Data Repository

public void Create<T>(T entity) where T : class
        {
            Context.Set<T>().Add(entity);
        }
We typed a generic Create method using the generic Set<T>( ) method from the DbContext.
Now, Retrieve will support 3 cases :
   1) retrieve ALL records : if both parameters ID and PRED are empty : it's sensible, isn't it?
   2) retrieve just ONE record : if ID contains a value
   3) retrieve SELECTED records according to a PREDICATE : if the PRED parameter is set :
Data Repository ASP.NET MVC 4

public List<T> Retrieve<T>(int? Id, Func<T, bool> pred) where T : class
        {
            List<T> list = new List<T>();
            if (Id.HasValue)
            {
                list.Add(Context.Set<T>().Find(Id.Value));
            }
            else if (pred != null)
            {
                list = Context.Set<T>().Where(pred).ToList();
            }
            else list = Context.Set<T>().ToList();
            return list;
        }
Now for the UPDATE method, just get the local entry, and set its state to "modified" :

public void Update<T>(T entity) where T : class
        {
            var e = Context.Entry<T>(entity);
            e.State = EntityState.Modified;
        }
Finally, DELETE just removes the entity : 
Repository ASP.NET MVC 4
public void Delete<T>(T entity) where T : class
        {
            Context.Set<T>().Remove(entity);
        }
That's all the GENERIC Repository.

How to use it? Example of using it on a Controller:
Get ALL records : 
Generic Data Repository

Get a LIST of SOME records : 

Generic Data Repository in MVC 4

Get just ONE record : 
 CREATE a new record : 


UPDATE a record : 


DELETE a record :

 This is the complete Generic Data Repository code for you:
public class DataRepository : IDisposable
    {
        #region Context
        private BlogEntities _Context;
        public BlogEntities Context
        {
            get
            {
                if (_Context == null)
                {
                    _Context = new BlogEntities();
                }
                return _Context;
            }

        }
        #endregion
        ///////// GENERIC C R U D METHODS :
        public void Create<T>(T entity) where T : class
        {
            Context.Set<T>().Add(entity);
        }
        public List<T> Retrieve<T>(int? Id, Func<T, bool> pred) where T : class
        {
            List<T> list = new List<T>();
            if (Id.HasValue)
            {
                list.Add(Context.Set<T>().Find(Id.Value));
            }
            else if (pred != null)
            {
                list = Context.Set<T>().Where(pred).ToList();
            }
            else list = Context.Set<T>().ToList();
            return list;
        }
        public void Update<T>(T entity) where T : class
        {
            var e = Context.Entry<T>(entity);
            e.State = EntityState.Modified;
        }
        public void Delete<T>(T entity) where T : class
        {
            Context.Set<T>().Remove(entity);
        }
        public bool Save(object target, int RecordsNumber)
        {
            try
            {
                return Context.SaveChanges() == RecordsNumber;
            }
            catch (OptimisticConcurrencyException)
            {
                ObjectContext ctx = ((IObjectContextAdapter)Context).ObjectContext;
                ctx.Refresh(RefreshMode.ClientWins, target);
                return Context.SaveChanges() == RecordsNumber;
            }
        }

        public void Dispose()
        {
            if (Context != null)
            {
                Context.Dispose();
                GC.Collect();
            }
        }
    }



That's All !!!! 
In this tutorial we've learned how to create a  Generic Data Repository in ASP.NET MVC 4.  

Happy programming.....


כתב: כרמל שוורצמן

Monday, January 13, 2014

Step By Step How to create an Action Method to Delete an Item

       By Carmel Schvartzman

In this tutorial we'll learn how to code an Action Method to  Delete an Item from an SQL SERVER database in ASP.NET MVC 4, in order to enable support to all CRUD (Create Retrieve Update Delete) operations in our application.
An Action method is a public method in a Controller, called in response to an user interaction. When a user send a request to an MVC app, the MVC framework find the appropriate Controller routing the request to it, and calling an Action method. This Action method returns an ActionResult object, which can be one of the following:
1. ViewResult : renders an MVC View
2. PartialViewResult : renders a section of a View
3. FileResult : returns binary data in the response
4. JsonResult : returns serialized Json object
5. JavaScriptResult : returns a script to be executed in the user browser
6. RedirectResult : redirects to another Action by URL
7. RedirectToRouteResult : redirects to another Action

There is also an EmptyResult, to return null.
Every public method in a Controller is suposed to be an Action. We can place private methods in a Controller, and if we need a public method that is not an Action, it must be decorated by an NonActionAttribute, which is translated by MVC to an 404 error (Page Not Found).

An Action method can handle different HTTP Verbs by using the AcceptVerbsAttribute, or the following more specific attributes:
1. HttpGetAttribute (for retrieving data)
2. HttpPostAttribute (for creating new entries)
3. HttpPutAttribute (for updating data)
4. HttpDeleteAttribute (for deleting)

When an Action method returns a View, we can pass data to the View using the ViewDataDictionary collection, this way:
                ViewData["Some Key"] = "Some Value";

Also , the View object supports getting any strongly-typed object as an argument:
                return View(someObject);

In the case an Action must pass data to another Action, this data is stored in a Session collection named TempDataDictionary:
               TempData["SomeKey"] = someObject;

This is useful while redirecting to another Action, or when sending a message to another Action in case of errors.


We'll add an Action Method to Delete an Item and save it in a database table  in ASP.NET MVC 4 , resulting in the following Delete View :



Let's say we have an MVC app connected to a database with an Entity Framework data model. First we'll create a DataRepository which supports retrieve and create actions. Create a new class BlogRepository:



In the new class, create a property with only the "get" access modifier to worry for creating the Data Model context:

Also, make the Repository implement the IDisposable interface, in order to dispose it after use:


Code the implementation of IDisposable:


We'll need also a method for retrieving ONLY ONE post to be deleted. Create the method, and get the required post from the store, not from Cache (if you try to use the post cached in memory, it will be detached from the data context):


Create a "Save" method to persist the data to the store:



And create an "Delete" method to delete a post:


The code will also remove the collection from the Cache, because the cache data is now obsolete, after the deletion.

Now we're ready to create our Controller and its Action methods. Add a new Controller named "BlogController":




The template to be used will be "MVC Controller with empty read/write actions":





Open the new Controller and find the "Delete" Action, and add the following code to render the details of the required post:



Now let's add a View to render the list. Choose creating a strongly-typed View, with the Blog Model:




The Scaffold Template must be "Delete" in this case.

The "Delete" View inside the "Blog" folder has been automatically created.
Open the new Controller and find the "Delete" Action, with "HttpPost" attribute decorating it:



Write the following code to delete a post using the Repository:


Notice that we're calling Save() after deleting the post. Also notice that we replaced the parameter type of the method, to a "Blog" type, which is received from the browser through an POST request.

Now let's see how our Action method works. Debug the project (F5), and browse to the "Blog" page .
Once there, select some entry and press "Delete":



We get the "Delete" View, to delete the Blog post:




Press the "Delete" button, to erase the entry.
The post has been deleted, and also it is reflected in the "Index" View, because the Cache has been refreshed:



In this tutorial we have learned how to create an Action Method to delete an item in a database table  in ASP.NET  MVC 4, using a Repository with caching support.

That's all!! 
Happy programming.....


כתב: כרמל שוורצמן

Thursday, December 26, 2013

Step By Step How to create a Data Repository with Data Caching in ASP.NET MVC 4

         By Carmel Schvartzman

In this tutorial we'll learn how to create a Data Repository with Data Caching in ASP.NET MVC 4. The MVC C# code for this step-by-step tutorial is available for download on GitHub at :
https://github.com/CarmelSoftware/Data-Repository-with-Data-Caching-in-ASP.NET-MVC-4
Its GitHub Wiki page is:
https://github.com/CarmelSoftware/Data-Repository-with-Data-Caching-in-ASP.NET-MVC-4/wiki

The Data Repository is a class which is designed to implement the Repository Pattern. This software pattern was created in order to access, cache in memory and persist in the database the application data. That means, the Repository will fetch the data ONLY IF IT'S NOT AVAILABLE IN MEMORY. 
There are, however, Repository implementations with no use of caching. The caching only stands to avoid unnecesary round trips to the SQL server. But when scalability of the sites is on the stage, may be we don't want to choke our web server's memory. Then, caching is not only redundant, but also dangerous as a waste of the web server resources. Of course using the Cache or the Application storages is less wasteful than using the Session ASP.NET storage, but even then the RAM memory of the web server should be taken into account and preserved as much as possible.
In this tutorial we'll add a Repository functionality with caching support to a new ASP.NET MVC 4 app.
Let's say we have an MVC internet application with an Entity Data Model mapped to an SQL server database. This EDM maps just two entities: Blog and Comment:

Our Repository will be added to the Model folder, which holds all the bussiness logic of the MVC application. Therefore focus the Model folder and create a new class: MyDataRepository.

Next, we'll create our Data Context, using the class created by the Entity Framework, inheriting DbContext: this class will be located under the Entity Data Model .edmx node: just open it until you see the XXX.Context.cs file:

 open it to see the name of your data context class which inherits from DbContext:

 This is your Data context and you'll add it to the Repository:

 Also add a null check to be sure your DbContext is there:

 Enclose the properties in a region:

 Take a look at the DbContext: you'll see that the Blog and Comment entities are represented by generic collections with a type DbSet<> :


 DbSet class provides the CRUD (Create Retrieve Update Delete) functionality we'll need to persist data changes to the database:


 The first method we'll add to our Repository will be the Save method. We separate this functionality so then we could make several changes all together and, just when done, we'll call the Repository Save method:



Now is time of designing the caching mechanism to store in memory the data. We'll use the caching infraestructure from the System.Runtime.Caching library, therefore add the pertinent reference:



Now focusing on the Model folder, create a new class named MyCachingProvider:



The class will use the ObjectCache, so add a private property to provide it. Implement the Get function instantiating the MemoryCache:



The first method we'll implement in our caching facility will be the Add functionality,and we'll take advantage of a MemoryCache aspect which puts this kind of storage far before from another storages like Application or Session: the caching policy. Later we'll state a caching expiration of a whole hour:




Now add the Remove functionality:



Also append the IsInMemory(key) method to check whether the required data is in memory:


Finally code the FetchData() method to get the data stored in memory:




 Next, we'll add all CRUD functionality to our Repository, as follows:



Notice that every C_UD (Create Update Delete) operation evicts the Comments from the Cache: that is because when a Comment is updated, created or deleted, the cached list remains in a async state with the actual data persisted in the database. We can either use the Sql Cache Dependencies functionality of the framework, or just evict the data from cache every time it is changed. For simplicity, we'll choose this later option.

 Finally, add the Retrieve functionality also for ALL the Comments and for just ONE selected Comment:


In the code you'll notice the use of the Caching functionality: first we check whether the data is in memory: if so we use the cache; elsewhere we fetch the data from the database and refresh the cache.


The RetrieveComment(id) method makes use of the previous RetrieveComment() method to get the List<> from memory:



 Now, let's check how our Repository works. On the server view, check the Comments table:


 Open the table contents, and clear them:




 Now, create a Testing class to run tests against the Repository. Inside the class, instantiate the Repository and create a new Comment:


 Next, call the Repository's AddComment() method, and Save() it all:


 Finally, in the HomeController make a call to our Test class:

 Build and debug the MVC application:



 As you can see, the original Comment has been instantiated.

 When finished the run, refresh the Comments table:



 The new record has been persisted by the Repository to the database.
Do it all again, adding the Retrieve part of the testing, fetching two comments to verify that the SECOND time we try to get data, it is loaded from the cache and not from database:


We get the Comment with CommentID = 2, as required:


Finally, test the Update method of the Repository, adding the code to change the Comment data:




Set a breakpoint inside the RetrieveComment() method to see how the "IF" clause causes to fetch data from the cache instead of from the database:





We've seen how to create a Data Repository with Data Caching in ASP.NET MVC 4 with support for all CRUD operations.
That's all!! 

Happy programming.....


כתב: כרמל שוורצמן