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文件中。

相关文章
相关标签/搜索