框架搭建
- 先創(chuàng)建Model
- 創(chuàng)建數(shù)據(jù)訪問接口層.IUserInfoDal
在該接口中定義了常見的方法CRUD以及分頁方法
public interface IUserInfoDal
{
IQueryable<UserInfo> LoadEntities(System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda);
IQueryable<UserInfo> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda, System.Linq.Expressions.Expression<Func<UserInfo, s>> orderbyLambda, bool isAsc);
bool DeleteEntity(UserInfo entity);
bool EditEntity(UserInfo entity);
UserInfo AddEntity(UserInfo entity);
}
- 每個(gè)接口中都需要CURD以及分頁方法的定義,而且這些方法的定義基本上是一致的,所以封裝.封裝到IBaseDal
public interface IBaseDal<T>where T:class,new()//注意該泛型的使用
{
IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda);
IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc);
bool DeleteEntity(T entity);
bool EditEntity(T entity);
T AddEntity(T entity);
}
- 讓IUserInfoDal繼承IBaseDal
public interface IUserInfoDal:IBaseDal<UserInfo>
{
//定義自己特有的方法。
}
- 讓具體的數(shù)據(jù)操作類UserInfoDal去實(shí)現(xiàn)IUserInfoDal接口中的方法
public class UserInfoDal :IUserInfoDal
{
OAEntities Db = new OAEntities();
/// <summary>
/// 查詢過濾
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<UserInfo> LoadEntities(System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda)
{
return Db.UserInfo.Where<UserInfo>(whereLambda);//
}
/// <summary>
/// 分頁
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalCount"></param>
/// <param name="whereLambda"></param>
/// <param name="orderbyLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public IQueryable<UserInfo> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda, System.Linq.Expressions.Expression<Func<UserInfo, s>> orderbyLambda, bool isAsc)
{
var temp = Db.UserInfo.Where<UserInfo>(whereLambda);
totalCount = temp.Count();
if (isAsc)//升序
{
temp = temp.OrderBy<UserInfo, s>(orderbyLambda).Skip<UserInfo>((pageIndex - 1) * pageSize).Take<UserInfo>(pageSize);
}
else
{
temp = temp.OrderByDescending<UserInfo, s>(orderbyLambda).Skip<UserInfo>((pageIndex - 1) * pageSize).Take<UserInfo>(pageSize);
}
return temp;
}
/// <summary>
/// 刪除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool DeleteEntity(UserInfo entity)
{
Db.Entry<UserInfo>(entity).State = System.Data.EntityState.Deleted;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 更新
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool EditEntity(UserInfo entity)
{
Db.Entry<UserInfo>(entity).State = System.Data.EntityState.Modified;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 添加數(shù)據(jù)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public UserInfo AddEntity(UserInfo entity)
{
Db.Set <UserInfo>().Add(entity);
Db.SaveChanges();
return entity;
}
}
- 由于每個(gè)數(shù)據(jù)操作類都要實(shí)現(xiàn)自己的接口(每一個(gè)接口都繼承了IBaseDal),所以每個(gè)數(shù)據(jù)操作類中都要重復(fù)實(shí)現(xiàn)CURD以及分頁的方法,所以把具體的實(shí)現(xiàn)封裝到了BaseDal中。
public class BaseDal<T>where T:class,new()
{
OAEntities Db = new OAEntities();
/// <summary>
/// 查詢過濾
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return Db.Set <T>().Where<T>(whereLambda);//
}
/// <summary>
/// 分頁
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalCount"></param>
/// <param name="whereLambda"></param>
/// <param name="orderbyLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc)
{
var temp = Db.Set<T>().Where<T>(whereLambda);
totalCount = temp.Count();
if (isAsc)//升序
{
temp = temp.OrderBy<T, s>(orderbyLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
}
else
{
temp = temp.OrderByDescending<T, s>(orderbyLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
}
return temp;
}
/// <summary>
/// 刪除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool DeleteEntity(T entity)
{
Db.Entry<T>(entity).State = System.Data.EntityState.Deleted;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 更新
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool EditEntity(T entity)
{
Db.Entry<T>(entity).State = System.Data.EntityState.Modified;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 添加數(shù)據(jù)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public T AddEntity(T entity)
{
Db.Set <T>().Add(entity);
Db.SaveChanges();
return entity;
}
}
- 讓UserInfoDal繼承BaseDal.
public class UserInfoDal : BaseDal<UserInfo>,IUserInfoDal
{
}
- 創(chuàng)建DBSession(數(shù)據(jù)會(huì)話層:就是一個(gè)工廠類,負(fù)責(zé)完成所有數(shù)據(jù)操作類實(shí)例的創(chuàng)建,然后業(yè)務(wù)層通過數(shù)據(jù)會(huì)話層來獲取要操作數(shù)據(jù)類的實(shí)例.所以數(shù)據(jù)會(huì)話層將業(yè)務(wù)層與數(shù)據(jù)層解耦. 在數(shù)據(jù)會(huì)話層中提供一個(gè)方法:完成所有數(shù)據(jù)的保存.)
private IUserInfoDal _UserInfoDal;
public IUserInfoDal UserInfoDal
{
get
{
if (_UserInfoDal == null)
{
_UserInfoDal = new UserInfoDal();
}
return _UserInfoDal;
}
set
{
_UserInfoDal = value;
}
}
- 在數(shù)據(jù)會(huì)話層中提供一個(gè)方法:完成所有數(shù)據(jù)的保存
/// <summary>
/// 一個(gè)業(yè)務(wù)中經(jīng)常涉及到對(duì)多張操作,我們希望連接一次數(shù)據(jù)庫,完成對(duì)張表數(shù)據(jù)的操作。提高性能。 工作單元模式。
/// </summary>
/// <returns></returns>
public bool SaveChanges()
{
return Db.SaveChanges() > 0;
}
- 將數(shù)據(jù)層中的所有的保存數(shù)據(jù)的SaveChanges注釋掉
- 在數(shù)據(jù)層中用到了EF的實(shí)例,數(shù)據(jù)會(huì)話層中也用到了,所以在一個(gè)請(qǐng)求中只能創(chuàng)建一個(gè)EF實(shí)例(線程內(nèi)唯一對(duì)象)
/// <summary>
/// 負(fù)責(zé)創(chuàng)建EF數(shù)據(jù)操作上下文實(shí)例,必須保證線程內(nèi)唯一.
/// </summary>
public class DBContextFactory
{
public static DbContext CreateDbContext()
{
DbContext dbContext = (DbContext)CallContext.GetData("dbContext");
if (dbContext == null)
{
dbContext = new OAEntities();
CallContext.SetData("dbContext", dbContext);
}
return dbContext;
}
}
- 在DBSession和BaseDal中調(diào)用上面的方法(CreateDbContext)完成EF實(shí)例的創(chuàng)建
// DBSession獲取EF實(shí)例
public DbContext Db
{
get
{
return DBContextFactory.CreateDbContext();
}
}
// BaseDal中獲取EF的實(shí)例
DbContext Db = DAL.DBContextFactory.CreateDbContext();
- 抽象抽象工廠封裝數(shù)據(jù)操作類實(shí)例創(chuàng)建,然后DBSession調(diào)用抽象工廠
/// <summary>
/// 通過反射的形式創(chuàng)建類的實(shí)例
/// </summary>
public class AbstractFactory
{
private static readonly string AssemblyPath = ConfigurationManager.AppSettings["AssemblyPath"];
private static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"];
public static IUserInfoDal CreateUserInfoDal()
{
string fullClassName = NameSpace + ".UserInfoDal";
return CreateInstance(fullClassName) as IUserInfoDal;
}
private static object CreateInstance(string className)
{
var assembly= Assembly.Load(AssemblyPath);
return assembly.CreateInstance(className);
}
}
// 然后修改DBSession
private IUserInfoDal _UserInfoDal;
public IUserInfoDal UserInfoDal
{
get
{
if (_UserInfoDal == null)
{
//_UserInfoDal = new UserInfoDal();
_UserInfoDal = AbstractFactory.CreateUserInfoDal();//通過抽象工廠封裝了類的實(shí)例的創(chuàng)建
}
return _UserInfoDal;
}
set
{
_UserInfoDal = value;
}
}
- 定義DBSession的接口
/// <summary>
/// 業(yè)務(wù)層調(diào)用的是數(shù)據(jù)會(huì)話層的接口。
/// </summary>
public interface IDBSession
{
DbContext Db { get; }
IUserInfoDal UserInfoDal { get; set; }
bool SaveChanges();
}
// 然后讓DBSession實(shí)現(xiàn)該接口
- 定義具體的業(yè)務(wù)基類
//在業(yè)務(wù)基類中完成DBSession的調(diào)用,然后將業(yè)務(wù)層中公共的方法定義在基類中,但是這些方法不知道通過DBSession來獲取哪個(gè)數(shù)據(jù)操作類的實(shí)例。所以將該業(yè)務(wù)基類定義成抽象類,加上一個(gè)抽象方法,加上一個(gè)IBaseDal屬性,并且讓基類的構(gòu)造方法調(diào)用抽象方法目的是在表現(xiàn)層new具體的業(yè)務(wù)子類,父類的構(gòu)造方法被調(diào)用,這些執(zhí)行抽象方法,但是執(zhí)行的的是子類中具體的實(shí)現(xiàn)。業(yè)務(wù)子類知道通過DBSession獲取哪個(gè)數(shù)據(jù)操作類的實(shí)例。
public abstract class BaseService<T> where T:class,new()
{
public IDBSession CurrentDBSession
{
get
{
return new DBSession();//暫時(shí)
}
}
public IDAL.IBaseDal<T> CurrentDal { get; set; }
public abstract void SetCurrentDal();
public BaseService()
{
SetCurrentDal();//子類一定要實(shí)現(xiàn)抽象方法。
}
public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return CurrentDal.LoadEntities(whereLambda);
}
}
- 定義業(yè)務(wù)層的接口
- 將數(shù)據(jù)庫鏈接字符串拷貝到web.config文件中