using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq.Expressions;
namespace Application.Linq
{
public class DataRepository<T> : IDataRepository<T>, IDataRepository where T : class
{
readonly NorthWindDataContext _dataContext;
public DataRepository()
{
_dataContext = new NorthWindDataContext();
}
public virtual T GetById(int ID)
{
var itemParameter = Expression.Parameter(typeof(T), "item");
var members = _dataContext.GetTable<T>().Context.Mapping.GetMetaType(typeof(T)).DataMembers;
string pk = members.Where(m => m.IsPrimaryKey == true).First().Name;
var whereExpression = Expression.Lambda<Func<T, bool>>
(
Expression.Equal(
Expression.Property(
itemParameter,
pk
),
Expression.Constant(ID)
),
new[] { itemParameter }
);
try
{
return GetAll().Where(whereExpression).Single();
}
catch
{
return null;
}
}
public virtual IQueryable<T> GetBySpecificKey(string KeyName, string KeyVal)
{
var itemParameter = Expression.Parameter(typeof(T), "item");
var whereExpression = Expression.Lambda<Func<T, bool>>
(
Expression.Equal(
Expression.Property(
itemParameter,
KeyName
),
Expression.Constant(KeyVal)
),
new[] { itemParameter }
);
try
{
return GetAll().Where(whereExpression).AsQueryable();
}
catch
{
return null;
}
}
public virtual IQueryable<T> GetAll()
{
return _dataContext.GetTable<T>();
}
public virtual void Insert(T entity)
{
_dataContext.GetTable<T>().InsertOnSubmit(entity);
_dataContext.SubmitChanges();
}
public virtual void Delete(T entity)
{
_dataContext.GetTable<T>().DeleteOnSubmit(entity);
_dataContext.SubmitChanges();
}
IQueryable IDataRepository.GetAll()
{
return GetAll();
}
void IDataRepository.Insert(object entity)
{
Insert((T)entity);
}
void IDataRepository.Delete(object entity)
{
Delete((T)entity);
}
object IDataRepository.GetById(int ID)
{
return GetById(ID);
}
IQueryable IDataRepository.GetBySpecificKey(string KeyName, string KeyVal)
{
return GetBySpecificKey(KeyName, KeyVal);
}
}
public interface IDataRepository<T> where T : class
{
T GetById(int ID);
IQueryable<T> GetAll();
void Insert(T entity);
void Delete(T entity);
IQueryable<T> GetBySpecificKey(string KeyName, string KeyVal);
}
public interface IDataRepository
{
object GetById(int ID);
IQueryable GetAll();
void Insert(object entity);
void Delete(object entity);
IQueryable GetBySpecificKey(string KeyName, string KeyVal);
}
}
//*********************************************************************************//
//*************************************END*****************************************//
//*********************************************************************************//
Now the time for concrete implementation of the pattern for the Products table:
*Note: The code below should ideally go to the Business Logic Layer. I am using Data Annotations here as I had hooked the Product Repository with an ObjectDataSource and plugged it to a simple GridView control to test the implementation.
//*********************************************************************************//
//*******************Concrete implementation for the pattern***********************//
//*********************************************************************************//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Application.Linq
{
/// <summary>
/// Concrete implementation of the repoistory for the Product table
/// </summary>
[System.ComponentModel.DataObject]
public class ProductRepository
{
/// <summary>
/// The product repository is instantiated
/// </summary>
readonly IDataRepository<Product> objProductRepository = new DataRepository<Product>();
/// <summary>
/// Get all products
/// </summary>
/// <returns>Returns a list of all products</returns>
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, true)]
public List<Product> GetAllProducts()
{
return objProductRepository.GetAll().ToList<Product>();
}
/// <summary>
/// Delete a product
/// </summary>
/// <param name="p">The product entity to be deleted</param>
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public void DeleteProduct(Product p)
{
objProductRepository.Delete(p);
}
/// <summary>
/// Gets a product by ID, assuming the Product ID is unique
/// </summary>
/// <param name="ProductID">The value for the primary key ProductID</param>
/// <returns>The product associated with the integer ID</returns>
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, true)]
public Product GetProductByID(int ProductID)
{
try
{
return objProductRepository.GetById(ProductID);
}
catch
{
return null;
}
}
}
}
//*********************************************************************************//
//*************************************END*****************************************//
//*********************************************************************************//
Using the concrete implementation with a GridView: