OA项目第一天

创建数据访问接口IBaseDal,业务层接口IBaseService等,具体的数据接口IUserinfoDal等等,创建数据会话层,EF线程内唯一,程序集创建类(工厂类)

OA项目第一天

首先做好我们的基本框架搭建

2J0lhe.png

MVC的请求管道

https://www.cnblogs.com/jiekzou/p/4896315.html

数据访问接口层的创建

通常我们的做法是从低到高,那么我们先来做好IDal层面的接口,先创建一个公共方法的IBaseDal,里面是我们通用的方法接口

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface IBaseDal<T> where T : class, new()
{
//查询
IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLamda);
//分页
IQueryable<T> LoadPageEntities(int pageindex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLamda, Expression<Func<T, bool>> orderbyLambda, bool isAsc);\
//增加
T AddEntity(T entity);
//删除
bool DeleteEntity(T entity);
//修改
bool EditEntity(T entity);
}

具体的比如IUserinfoDal引用IBaseDal

1
2
3
4
public interface IUserinfoDal: IBaseDal<UserInfo>
{
//这里只包含Userinfo自身的方法
}

数据层的创建

如果我们直接让UserInfoDal继承自IUserInfoDal是可以,但是现在我们里面的方法是增删改查分页,任何数据类都适用,因此最好的做法是建立一个BaseDal类,这里面实现我们这些通用的方法,然后我们具体的类再去继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class BaseDal<T> where T : class ,new()
{
OAEntities db = new OAEntities();
public T AddEntity(T entity)
{
entity= db.Set<T>().Add(entity);// 针对对上下文和基础存储中给定类型的实体的访问返回一个 System.Data.Entity.DbSet`1 实例。

return entity;
}

public bool DeleteEntity(T entity)
{
db.Entry<T>(entity).State = EntityState.Deleted;
return db.SaveChanges() > 0;
}

public bool EditEntity(T entity)
{
db.Entry<T>(entity).State = EntityState.Modified;
return db.SaveChanges() > 0;
}

public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLamda)
{
return db.Set<T>().Where<T>(whereLamda);
}

public IQueryable<T> LoadPageEntities<S>(int pageindex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLamda, Expression<Func<T, S>> orderbyLambda, bool isAsc)
{
var entity = db.Set<T>().Where<T>(whereLamda);
totalCount = entity.Count();
if (isAsc)
{
entity = entity.OrderBy<T,S>(orderbyLambda).Skip<T>((pageindex - 1) * pageSize).Take(pageSize);
}
else
{
entity = entity.OrderByDescending<T, S>(orderbyLambda).Skip<T>((pageindex - 1) * pageSize).Take(pageSize);
}

return entity;
}
}

UserinfoDal

1
2
3
public class UserInfoDal : BaseDal<UserInfo>, IUserinfoDal
{
}

创建数据会话层以及EF线程内唯一

之前我们的三层,表现层,业务层,数据层。现在我们在数据层和业务层之间再加上以个数据会话层,来用于创建数据实体类对象,业务层通过数据会话层来操作数据类的实例。可以看出数据会话层在于解耦。

数据会话层是一个工厂类,来获取实例,但是现在我们在这里面多加一个方法,完成所有的数据的保存,但是这样就需要new一个EF数据对象,这显然和dal层面的EF对象不一样,所以这时候我们要把上面的db.SaveChanges()注释掉,并且创建线程内唯一EF对象。

我们的DalFactory引用Dal,如果我们在DalFactory里面创建EF对象那么Dal就得引用DalFactory,这样一来就循环引用,因此我们把方法写在Dal层里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class DBcontextFactory
{
/// <summary>
/// 创建EF线程内唯一对象
/// </summary>
/// <returns></returns>
public static DbContext CreatDbContext()
{
DbContext dbContext = (DbContext) CallContext.GetData("dbcontext");
if (dbContext==null)
{
dbContext = new OAEntities();
CallContext.SetData("dbcontext",dbContext);
}
return dbContext;
}
}

DBSession数据会话层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 //数据会话层,工厂类,用于业务层调用数据层对象。此类作用就是创建数据类的实体对象。以及对数据进行保存
//Bll层调用的是数据会话层的接口,所以我们在IDal层新建一个IDBSession接口
public class DBSession:IDBSession
{
IUserinfoDal _userinfodal ;

public DbContext Db
{
get =>DAL.DBcontextFactory.CreatDbContext();

}

public IUserinfoDal UserinfoDal
{
get
{
if (_userinfodal == null)
{
//_userinfodal = new UserInfoDal(); 为了解耦我们使用程序集的方法创建
_userinfodal = DALFactory.AbstractFactory.CreatUserInfoDal();
}

return _userinfodal;
}
set => _userinfodal = value;
}
//保存数据的方法
public void SaveValueChange()
{
Db.SaveChanges();
}
}
1
2
3
4
5
6
public interface IDBSession
{
DbContext Db { get; }
IUserinfoDal UserinfoDal { get; set; }
bool SaveValueChange();
}

程序集创建类的实例,这样一来我们创建类的实例只要改配置文件就行了(抽象工厂创建类的实例)

配置文件的修改必须在表现层的config修改

1
2
3
4
<appSettings>
<add key="AssemblyPath" value="OAProject.DAL" />
<add key="NameSpace" value="OAProject.DAL" />
</appSettings>

工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AbstractFactory
{
private static readonly string AssemblyPath = ConfigurationManager.AppSettings["AssemblyPath"];
private static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"];

public static IUserinfoDal CreatUserInfoDal()
{
string fullclassName = NameSpace + ".UserInfoDal";
return CreateInstance(fullclassName) as UserInfoDal;
}

private static object CreateInstance(string className)
{
var assembly = Assembly.Load(AssemblyPath);
return assembly.CreateInstance(className);
}
}

接下来创建业务层BLL UserInfoService,先新建一个BaseServe,注意这里运用的多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public abstract class BaseService<T> where T:class, new()
{
public IDBSession CurrentDBSession
{
//get => new DBSession();//要是每次在业务层调用数据会话层都直接new一个这样不行,还是得县城内唯一
get => DBSessionFactory.CreatDBSession();

}

public IBaseDal<T> CurrentDal { get; set; }//所有的Dal都继承IBaseDal,子类可以赋值给父类。
public abstract void SetCurrentDal();

public BaseService()
{
SetCurrentDal();//在子类,必须实现这个方法,那么在子类实现的这个方法里面我们就给CurrentDal属性赋值,比如CurrentDal = CurrentDBSession.UserinfoDal;
}
public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLamda)
{
return CurrentDal.LoadEntities(whereLamda);//这里我们已经知道了CurrentDal是哪个子类Dal了
}
public T AddEntity(T entity)
{
entity = CurrentDal.AddEntity(entity);
CurrentDBSession.SaveValueChange();
//db.SaveChanges();
return entity;
}
public bool DeleteEntity(T entity)
{
CurrentDal.DeleteEntity(entity);
//return db.SaveChanges() > 0;
return CurrentDBSession.SaveValueChange();
}
public bool EditEntity(T entity)
{
CurrentDal.EditEntity(entity);
return CurrentDBSession.SaveValueChange();
}
public IQueryable<T> LoadPageEntities<S>(int pageindex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLamda, Expression<Func<T, S>> orderbyLambda, bool isAsc)
{
return CurrentDal.LoadPageEntities<S>(pageindex, pageSize, out totalCount, whereLamda, orderbyLambda, isAsc);
}
}

子类需实现父类的抽象方法,继承自接口

1
2
3
4
5
6
7
public class UserInfoService :BaseService<UserInfo>, IUserinfoServerice
{
public override void SetCurrentDal()
{
CurrentDal = CurrentDBSession.UserinfoDal;
}
}

IBaseService

1
2
3
4
5
6
7
8
9
10
11
12
public interface IBaseService<T> where T:class ,new ()
{
IDBSession CurrentDBSession { get; }
IBaseDal<T> CurrentDal { get; set; }
IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLamda);
T AddEntity(T entity);
bool DeleteEntity(T entity);
bool EditEntity(T entity);

IQueryable<T> LoadPageEntities<S>(int pageindex, int pageSize, out int totalCount,
Expression<Func<T, bool>> whereLamda, Expression<Func<T, S>> orderbyLambda, bool isAsc);
}
1
2
3
public interface IUserinfoServerice: IBaseService<UserInfo>
{
}

OA项目第一天
http://www.kju147.com/2018/04/15/OA项目第一天/
作者
个人学习
发布于
2018年4月15日
许可协议