APS.NET MVC + EF (14)---項目框架搭建

一:框架搭建 web

   

1:先建立Model. 數據庫

2:建立數據訪問接口層。IUserInfoDal 框架

在該接口中定義了常見的方法CURD以及分頁方法。 性能

public interface IUserInfoDal spa

{ 線程

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); ip

UserInfo AddEntity(UserInfo entity);

 

}

3:每一個接口中都須要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);

}

   

4:讓IUserInfoDal繼承IBaseDal

public interface IUserInfoDal:IBaseDal<UserInfo>

{

//定義本身特有的方法。

 

}

5:讓具體的數據操做類UserInfoDal去實現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>

/// 添加數據

/// </summary>

/// <param name="entity"></param>

/// <returns></returns>

public UserInfo AddEntity(UserInfo entity)

{

   

Db.Set <UserInfo>().Add(entity);

Db.SaveChanges();

return entity;

   

}

}

   

6:因爲每一個數據操做類都要實現本身的接口(每個接口都繼承了IBaseDal),因此每一個數據操做類中都要重複實現CURD以及分頁的方法,因此把具體的實現封裝到了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>

/// 添加數據

/// </summary>

/// <param name="entity"></param>

/// <returns></returns>

public T AddEntity(T entity)

{

   

Db.Set <T>().Add(entity);

Db.SaveChanges();

return entity;

   

}

   

7:讓UserInfoDal繼承BaseDal.

public class UserInfoDal : BaseDal<UserInfo>,IUserInfoDal

{

 

}

   

8:建立DBSession(數據會話層:就是一個工廠類,負責完成全部數據操做類實例的建立,而後業務層經過數據會話層來獲取要操做數據類的實例。因此數據會話層將業務層與數據層解耦。

/// 在數據會話層中提供一個方法:完成全部數據的保存。)

做用:封裝了數據層全部實例的建立,將BLL和DAL進行解耦,提供對數據操的統一訪問點。提供一個方法,完成全部數據的保存。

   

private IUserInfoDal _UserInfoDal;

public IUserInfoDal UserInfoDal

{

get {

if (_UserInfoDal == null)

{

_UserInfoDal = new UserInfoDal();

}

return _UserInfoDal;

}

set

{

_UserInfoDal = value;

}

}

 

9: /// <summary>

/// 一個業務中常常涉及到對多張操做,咱們但願連接一次數據庫,完成對張表數據的操做。提升性能。 工做單元模式。

/// </summary>

/// <returns></returns>

public bool SaveChanges()

{

return Db.SaveChanges() > 0;

}

   

   

10:將數據層中的全部的保存數據的SaveChanges註釋掉。

   

11:在數據層中用到了EF的實例,數據會話層中也用到了,因此在一個請求中只能建立一個EF實例(線程內惟一對象)        

   

/// <summary>

/// 負責建立EF數據操做上下文實例,必須保證線程內惟一.

/// </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;

}

}

   

12:在DBSession和BaseDal中調用上面的方法(CreateDbContext)完成EF實例的建立。

DBSession獲取EF實例

public DbContext Db

{

get

{

return DBContextFactory.CreateDbContext();

}

}

 

BaseDal中獲取EF的實例

 

DbContext Db = DAL.DBContextFactory.CreateDbContext();

   

   

13:抽象抽象工廠封裝數據操做類實例建立,而後DBSession調用抽象工廠。

在web.config 中配置數據層程序集的相關信息。

   

/// <summary>

/// 經過反射的形式建立類的實例

/// </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();//經過抽象工廠封裝了類的實例的建立

}

return _UserInfoDal;

}

set

{

_UserInfoDal = value;

}

}

   

14:定義DBSession的接口

/// <summary>

/// 業務層調用的是數據會話層的接口。

/// </summary>

public interface IDBSession

{

DbContext Db { get; }

IUserInfoDal UserInfoDal { get; set; }

bool SaveChanges();

}

   

而後讓DBSession實現該接口。

   

15:定義具體的業務基類

   

//在業務基類中完成DBSession的調用,而後將業務層中公共的方法定義在基類中,可是這些方法不知道經過DBSession來獲取哪一個數據操做類的實例。因此將該業務基類定義成抽象類,加上一個抽象方法,加上一個IBaseDal屬性,而且讓基類的構造方法調用抽象方法目的是在表現層new具體的業務子類,父類的構造方法被調用,這些執行抽象方法,可是執行的的是子類中具體的實現。業務子類知道經過DBSession獲取哪一個數據操做類的實例。

public abstract class BaseService<T> where T:class,new()

{

public IDBSession CurrentDBSession

{

get

{

return new DBSession();//暫時

}

}

public IDAL.IBaseDal<T> CurrentDal { get; set; }

public abstract void SetCurrentDal();

public BaseService()

{

SetCurrentDal();//子類必定要實現抽象方法。

}

public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)

{

   

 

return CurrentDal.LoadEntities(whereLambda);

}

   

}

   

16:定義業務層的接口。

17:保證業務層的DbSession線程內惟一

   

17:將數據庫連接字符串拷貝到web.config文件中。

相關文章
相關標籤/搜索