Monthly Archives: November 2011
Using Entity framework features Part 2
In the previous post, I talked about the advantages of using code first method and EF4.1/2 , created a sample model in a domain project, then added DataAccess project for direct use in an MVC project. Now I want to use data access in my service layer. How?
Recently i heard about repository pattern! So I’m implementing this in a new project and then i’ll complete the domain layer:
Before implementing the repository pattern i need an interface to access the DataAccess layer, So i create IDbContext interface in the Infrastructure library project:
public interface IDbContext
{
IDbSet Set() where T : class;
Database Db { get; }
int SaveChanges();
}
Now i add a Repository pattern to the project:
First i use an interface repository in Infrastructure project:
public interface IRepository where T : class
{
///
/// Create New Instance ///
T NewEntityInstance(); ///
/// Inserts an item ///
void Add(T item); ///
/// Deletes an item ///
void Remove(T item); ///
/// Get an item matching to prediate ///
T Get(Funcpredicate); ///
/// Get Count of items matching to predicate ///
int GetCount(Funcpredicate); ///
/// Get IEnumerable object matching to predicate ///
IEnumerableGetAll(Funcpredicate); ///
/// Get IEnumerable object matching to predicate,start index and count ///
IEnumerableGetAll(Funcpredicate, int start, int count); ///
/// Saves the pending changes back into the DataContext. ///
void Save();
}
And then put it in DataAccess project:
public class Repository : IRepository where T : class
{
protected IDbContext _Context;
protected IDbSet _DbSet;
public Repository(IDbContext context)
{
_Context = context;
_DbSet = _Context.Set();
}
public T NewEntityInstance()
{
return _DbSet.Create();
}
public void Add(T entity)
{
_DbSet.Add(entity);
}
public virtual IQueryable GetAll()
{
return _DbSet.AsQueryable();
}
public void Remove(T entity)
{
_DbSet.Remove(entity);
}
public T Get(Func predicate)
{
return _DbSet.FirstOrDefault(predicate);
}
public int GetCount(Func predicate)
{
return _DbSet.Count(predicate);
}
public IEnumerable GetAll(Func predicate)
{
return _DbSet.Where(predicate);
}
public IEnumerable GetAll(Func predicate, int start, int count)
{
return _DbSet.Where(predicate).Skip(start).Take(count);
}
public void Save()
{
try
{
_Context.SaveChanges();
}
catch (DbEntityValidationException e)
{
var s = e.EntityValidationErrors.ToList();
throw;
}
}
public IEnumerable GetQuery(string queryString, Func predicate = null) where K : class
{
if (predicate != null)
return _Context.Db.SqlQuery(queryString).Where(predicate);
return _Context.Db.SqlQuery(queryString);
}
}
Good, Service classes are ready to be used in Controllers and action methods.
How to create a service:
for example i wrote a simple service named MemberManager:
using System;
using System.Collections.Generic;
using Arash.Membership.Model;
namespace Arash.Core
{
public interface IMemberManager
{
Member MakeInstance();
void Add(Member entity);
void Edit(Member entity);
void Remove(Member entity);
int GetCount(Func predicate = null);
Member Get(Func predicate = null);
IEnumerable GetAll(Func predicate = null, int start = 0, int count = 6);
Member Authenticate(string username, string password);
}
}
implemented Member service class:
using System;
using System.Collections.Generic;
using Arash.Membership.Model;
using Arash.Utility.Common;
using Paradiso.Infrastructure.Data;
using Arash.Infrastructure.Data;
namespace Arash.Core.Manager
{
public class MemberManager : IMemberManager
{
private IRepository _repository;
public MemberManager(IRepository repository)
{
_repository = repository;
}
public Member MakeInstance()
{
return _repository.NewEntityInstance();
}
public void Add(Member entity)
{
_repository.Add(entity);
_repository.Save();
}
public void Edit(Member entity)
{
_repository.Save();
}
public void Remove(Member entity)
{
_repository.Remove(entity);
_repository.Save();
}
public int GetCount(Func predicate = null)
{
return predicate == null
? _repository.GetCount(p => true)
: _repository.GetCount(predicate);
}
public Member Get(Func predicate = null)
{
return predicate == null
? _repository.Get(p => true)
: _repository.Get(predicate);
}
public IEnumerable GetAll(Func predicate = null, int start = 0, int count = 6)
{
return predicate == null
? _repository.GetAll(p => true)
: start == 0
? _repository.GetAll(predicate)
: _repository.GetAll(predicate, start, count);
}
public Member Authenticate(string username, string password)
{
var entity = _repository.Get(p => p.Username == username);
if (entity == null)
return null;
var passwordHash = PasswordGenerator.GetHashPassword(password);
if (!string.Equals(passwordHash, password))
return null;
return entity;
}
}
}
Conclusion:
We learned how to implement some layers in n-layer architecture. Ofcourse you can download source codes of posts part1 and 2 from github