Nous commençons cette série d’articles sur la nouvelle version de Entity Framework qui sera disponible dans le Framework .NET 4.0 avec Visual Studio 2010, actuellement en Beta 2.
Dans le version initiale de Entity Framework il étais assez difficile de mettre en place le Design Pattern Repository.
Maintenant Entity Framework 4 nous offre une interface commune IObjectSet(TEntity) Interface pour accéder a nos entités utilisable via l’ObjectContext qui offre une méthode générique CreateObjectSet(TEntity)() nous permettant de modifier nos objets de données.
Sean Fao a mis en œuvre sur son blog une simple et efficace implémentation de ce pattern Repository, non seulement une Repository mais une Repository Generique !
public interface IRepository<T> : IDisposable where T : class
{
IQueryable<T> Fetch();
IEnumerable<T> GetAll();
IEnumerable<T> Find(Func<T, bool> predicate);
T Single(Func<T, bool> predicate);
T First(Func<T, bool> predicate);
void Add(T entity);
void Delete(T entity);
void Attach(T entity);
void SaveChanges();
void SaveChanges(SaveOptions options);
}
/// <summary>
/// A generic repository for working with data in the database
/// </summary>
/// <typeparam name="T">A POCO that represents an Entity Framework entity</typeparam>
public class DataRepository<T> : IRepository<T> where T : class
{
/// <summary>
/// The context object for the database
/// </summary>
private ObjectContext _context;
/// <summary>
/// The IObjectSet that represents the current entity.
/// </summary>
private IObjectSet<T> _objectSet;
/// <summary>
/// Initializes a new instance of the DataRepository class
/// </summary>
public DataRepository()
: this(new AdventureWorksEntities())
{
}
/// <summary>
/// Initializes a new instance of the DataRepository class
/// </summary>
/// <param name="context">The Entity Framework ObjectContext</param>
public DataRepository(ObjectContext context)
{
_context = context;
_objectSet = _context.CreateObjectSet<T>();
}
/// <summary>
/// Gets all records as an IQueryable
/// </summary>
/// <returns>An IQueryable object containing the results of the query</returns>
public IQueryable<T> Fetch()
{
return _objectSet;
}
/// <summary>
/// Gets all records as an IEnumberable
/// </summary>
/// <returns>An IEnumberable object containing the results of the query</returns>
public IEnumerable<T> GetAll()
{
return GetQuery().AsEnumerable();
}
/// <summary>
/// Finds a record with the specified criteria
/// </summary>
/// <param name="predicate">Criteria to match on</param>
/// <returns>A collection containing the results of the query</returns>
public IEnumerable<T> Find(Func<T, bool> predicate)
{
return _objectSet.Where<T>(predicate);
}
/// <summary>
/// Gets a single record by the specified criteria (usually the unique identifier)
/// </summary>
/// <param name="predicate">Criteria to match on</param>
/// <returns>A single record that matches the specified criteria</returns>
public T Single(Func<T, bool> predicate)
{
return _objectSet.Single<T>(predicate);
}
/// <summary>
/// The first record matching the specified criteria
/// </summary>
/// <param name="predicate">Criteria to match on</param>
/// <returns>A single record containing the first record matching the specified criteria</returns>
public T First(Func<T, bool> predicate)
{
return _objectSet.First<T>(predicate);
}
/// <summary>
/// Deletes the specified entitiy
/// </summary>
/// <param name="entity">Entity to delete</param>
/// <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>
public void Delete(T entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_objectSet.DeleteObject(entity);
}
/// <summary>
/// Deletes records matching the specified criteria
/// </summary>
/// <param name="predicate">Criteria to match on</param>
public void Delete(Func<T, bool> predicate)
{
IEnumerable<T> records = from x in _objectSet.Where<T>(predicate) select x;
foreach (T record in records)
{
_objectSet.DeleteObject(record);
}
}
/// <summary>
/// Adds the specified entity
/// </summary>
/// <param name="entity">Entity to add</param>
/// <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>
public void Add(T entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_objectSet.AddObject(entity);
}
/// <summary>
/// Attaches the specified entity
/// </summary>
/// <param name="entity">Entity to attach</param>
public void Attach(T entity)
{
_objectSet.Attach(entity);
}
/// <summary>
/// Saves all context changes
/// </summary>
public void SaveChanges()
{
_context.SaveChanges();
}
/// <summary>
/// Saves all context changes with the specified SaveOptions
/// </summary>
/// <param name="options">Options for saving the context</param>
public void SaveChanges(SaveOptions options)
{
_context.SaveChanges(options);
}
/// <summary>
/// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
/// </summary>
/// <param name="disposing">A boolean value indicating whether or not to dispose managed resources</param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}
Notre Repository Generique est maintenant utilisable très simplement dans nos applications
using (IRepository<Employee> repository = new DataRepository<Employee>())
{
this.GridView1.DataSource = from x in repository.Fetch()
select new
{
x.MaritalStatus,
x.Contact.FirstName,
x.Contact.LastName,
x.BirthDate
};
this.GridView1.DataBind();
}
Dans un prochain article nous verrons comment étendre cette Repository Generique afin d’améliorer les performances en utilisant le Cache.
7dffe953-4b1b-4b13-93c0-4faeda52cca4|1|5.0
C#, Visual Studio 2010, Entity Framework
entity framework 4, c#, visual studio 2010