MVC小型商务网站实例(3)--Repository模式

Repository翻译为资源库, 通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调。使用该模式可以将领域模型从客户代码和数据映射层之间解耦出来。

首先我们将数据操作的相同部份抽象出一个接口IRepository<T>,然后让各实体操作类实现此接口,代码:

 

public interface IRepository<T>
{
void Add(T entity);
void Del(T entity);
void Del(ICriteria criteria);
void Update(int entityId, T entity);
T Find(
int entityId);
IList
<T> Find(ICriteria criteria);
IList
<T> FindAll();
IList
<T> Find(ICriteria criteria, int pageIndex, int pageSize, Order orderExpr);
IQueryable
<T> FindQueryable(ICriteria criteria, int page, int pageSize, Order orderExpr);
int Count(ICriteria criteria);
void SaveChanges();
void AcceptAllChanges();
}

 

然后实现这个公共操作类BaseRepositoryBase<T>:

 

/// <summary>
/// 数ºy据Y仓?储ä¡é基¨´类¤¨¤
/// </summary>
/// <typeparam name="T">EF数ºy据Y类¤¨¤</typeparam>
public abstract class BaseRepositoryBase<T> : IRepository<T> where T : class
{
protected SouthShopEntities1 dataContext;

private string _entitiesSetName;

public BaseRepositoryBase()
{
this.dataContext = BaseRepository.CreateDataContext();
}

public BaseRepositoryBase(bool defaultEntitySetName)
{
this.dataContext = BaseRepository.CreateDataContext();
if (defaultEntitySetName)
{
if (EntitySetName.EndsWith("y"))
{
this._entitiesSetName = StringExtensions.RemoveChars(EntitySetName, EntitySetName.Length - 1) + "ies";
}
else
{
this._entitiesSetName = EntitySetName + "s";
}
}
else
{
throw new ArgumentNullException("entitiesSet");
}

}

public BaseRepositoryBase(SouthShopEntities1 dataContext, string entitiesSetName)
{
if (dataContext == null)
throw new ArgumentNullException("DataContext");
if (String.IsNullOrEmpty(entitiesSetName))
throw new ArgumentNullException("entitiesSet");

this.dataContext = dataContext;
this._entitiesSetName = entitiesSetName;
}

/// <summary>
/// 实º¦Ì体¬?类¤¨¤名?称?
/// </summary>
protected string EntitySetName
{
get { return typeof(T).Name; }
}

/// <summary>
/// 实º¦Ì体¬?集¡¥名?称?
/// </summary>
protected string EntitiesSetName
{
get { return _entitiesSetName; }
set { _entitiesSetName = value; }
}

/// <summary>
/// 实º¦Ì体¬?集¡¥对?象¨®
/// </summary>
protected ObjectQuery<T> EntitySet
{
get { return dataContext.CreateQuery<T>("[" + EntitiesSetName + "]"); }
}

#region IRepository<T> 成¨¦员¡À

public virtual void Add(T entity)
{
dataContext.AddObject(EntitiesSetName, entity);
}

public virtual void Del(T entity)
{
dataContext.DeleteObject(entity);
}

public virtual void Del(ICriteria criteria)
{
IEnumerable
<T> query = EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray());
foreach (var item in query)
{
dataContext.DeleteObject(item);
}
dataContext.SaveChanges();
}

public virtual void Update(int entityId, T entity)
{
T t
= Find(entityId);
t
= entity;
dataContext.ApplyPropertyChanges(EntitiesSetName, t);
}

public IList<T> Find(ICriteria criteria)
{
if (criteria == null)
throw new ArgumentNullException("criteria");
var query
= EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray());
//var str = query.ToTraceString();
return ToList(query);
}

public IList<T> FindAll()
{
return ToList(EntitySet);
}

public IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr)
{
if (criteria == null || orderExpr == null)
throw new ArgumentNullException("criteria");
var query
= EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray());


return ToList(orderExpr.OrderFrom<T>(query).Skip((page - 1) * pageSize).Take(pageSize));
}

public IQueryable<T> FindQueryable(ICriteria criteria, int page, int pageSize, Order orderExpr)
{
if (criteria == null || orderExpr == null)
throw new ArgumentNullException("criteria");
var query
= EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray());

return orderExpr.OrderFrom<T>(query).Skip((page - 1) * pageSize).Take(pageSize);
}

public int Count(ICriteria criteria)
{
if (criteria == null)
throw new ArgumentNullException("criteria");
return EntitySet.Where(criteria.Expression, criteria.Parameters.Select(p => new ObjectParameter(p.Name, p.Value)).ToArray()).Count();
}

public void SaveChanges()
{
dataContext.SaveChanges();
}

public void AcceptAllChanges()
{
dataContext.AcceptAllChanges();
}

public virtual T Find(int entityId)
{
return Find(new EqualParameterCriteria(EntitySetName + "Id", entityId)).FirstOrDefault();
}

protected virtual IList<T> ToList(IQueryable<T> query)
{
try
{
return query.AsEnumerable().Select(c => c).Cast<T>().ToList();
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
}

#endregion
}

接下来各表的业务处理再单独定义另外一个接口,让它继承 IRepository<T> 如:

 

public interface IProductRepository<T>:IRepository<T> where T :class
{
void Del(IEnumerable<int> values);
int GetProductId(string productName);
IEnumerable
<ProductList> GetCategoryHotSell(int categoryId);
}

这样做的目的是项目采用了IOC容器(Castle Windsor)进行解耦,还可以实现一些非公共业务处理。

最后该实体的Repository类实现如下:

public class ProductRepository: BaseRepositoryBase<Product>, IProductRepository<Product>
{
public ProductRepository()
{
this.EntitiesSetName = "Products";
}

public void Del(IEnumerable<int> values)
{
var query
= this.EntitySet.Where(ContainsCriteria.ContainsExpression<Product, int>(c => c.ProductId, values)).ToList();
foreach (var value in query)
{
this.dataContext.DeleteObject(value);
}
this.SaveChanges();
}

public int GetProductId(string productName)
{
var query
= from p in this.EntitySet
where p.ProductName == productName
select p.ProductId;

return query.FirstOrDefault();
}

public IEnumerable<ProductList> GetCategoryHotSell(int categoryId)
{
var query
= (from p in this.EntitySet
where p.CategoryId == categoryId
orderby p.SellAmount descending
select
new ProductList
{
CategoryId
= categoryId,
ProductId
= p.ProductId,
ProductName
= p.ProductName
}).Take(
10).ToList();

return query;
}
}

这样我们就实现了Repository模式。

posted on 2011-03-18 11:31  Ω元素  阅读(1966)  评论(4编辑  收藏  举报

导航