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.
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:
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:
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:
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 :
How to use it? Example of using it on a Controller:
Get ALL records :
UPDATE a record :
This is the complete Generic Data Repository code for you:
That's All !!!!
In this tutorial we've learned how to create a Generic Data Repository in ASP.NET MVC 4.
Happy programming.....
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:
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:
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:
public bool Save(object target, int RecordsNumber)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.
{
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();
}
}
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:
public void Create<T>(T entity) where T : classWe typed a generic Create method using the generic Set<T>( ) method from the DbContext.
{
Context.Set<T>().Add(entity);
}
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 :
public List<T> Retrieve<T>(int? Id, Func<T, bool> pred) where T : classNow for the UPDATE method, just get the local entry, and set its state to "modified" :
{
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;
}
Finally, DELETE just removes the entity :
public void Delete<T>(T entity) where T : classThat's all the GENERIC Repository.
{
Context.Set<T>().Remove(entity);
}
How to use it? Example of using it on a Controller:
Get ALL records :
Get a LIST of SOME records :
Get just ONE record :
CREATE a new record : UPDATE a record :
DELETE a record :
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 !!!!
Happy programming.....
כתב: כרמל שוורצמן
No comments:
Post a Comment