第一次寫博客,想了半天先從簡(jiǎn)單的三層架構(gòu)開始吧,希望能幫助到你! 簡(jiǎn)單介紹一下三層架構(gòu), 三層架構(gòu)從上到下分:表現(xiàn)層(UI),業(yè)務(wù)邏輯層(BLL),數(shù)據(jù)訪問層(DAL)再加上數(shù)據(jù)模型(Model),用ef訪問數(shù)據(jù)庫,Model也就是與數(shù)據(jù)庫表映射的實(shí)體。廢話少說,上代碼。
為方便說明,新建一個(gè)實(shí)體模型UserInfo,數(shù)據(jù)庫表中應(yīng)該對(duì)應(yīng)一個(gè)UserInfo表,至于怎樣建立表,有多種方式,用ef來建立表比較方便。具體怎樣用ef訪問數(shù)據(jù)庫,后續(xù)會(huì)在其他文章中解釋,敬請(qǐng)關(guān)注。 1 public class UserInfo 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public short Age { get; set; } 6 }
首先設(shè)計(jì)通用的CRUD基接口IBaseDal,作為通用的數(shù)據(jù)庫訪問通道。 1 public interface IBaseDal<T> where T : class,new() 2 { 3 void Add(T entity); 4 void Delete(T entity); 5 void Update(T entity); 6 IQueryable<T> GetEntities(Expression<Func<T, bool>> expression); 7 IQueryable<T> GetEntitiesByPage<TKey>(int pageSize, int pageIndex, bool isAsc, Expression<Func<T, TKey>> keySelector, Expression<Func<T, bool>> expression); 8 bool SaveChanges(); 9 } 以UserInfo實(shí)體為例,繼承IBaseDal接口 public interface IUserInfoDal : IBaseDal<UserInfo> { } 接口設(shè)計(jì)完成,設(shè)計(jì)通用基類,這里存在變化點(diǎn),本例用ef實(shí)現(xiàn),如果以后通過其他實(shí)體框架或者直接通過ado.net訪問數(shù)據(jù)庫,只需要改動(dòng)這個(gè)類。 public class BaseDal<T> where T : class,new() { private DbContext dbContext = DbContextFactory.DbContext; public void Add(T entity) { dbContext.Set<T>().Add(entity); } public void Delete(T entity) { dbContext.Entry(entity).State = EntityState.Deleted; } public void Update(T entity) { dbContext.Entry(entity).State = EntityState.Modified; } public IQueryable<T> GetEntities(Expression<Func<T, bool>> expression) { return dbContext.Set<T>().Where(expression); } public IQueryable<T> GetEntitiesByPage<TKey>(int pageSize, int pageIndex, bool isAsc, Expression<Func<T, TKey>> keySelector, Expression<Func<T, bool>> expression) { if (isAsc) //升序 { return dbContext.Set<T>().Where(expression).OrderBy(keySelector).Skip((pageIndex - 1) * pageSize).Take(pageSize); } else //降序 { return dbContext.Set<T>().Where(expression).OrderByDescending(keySelector).Skip((pageIndex - 1) * pageSize).Take(pageSize); } } public bool SaveChanges() { return dbContext.SaveChanges() > 0; } } public static class DbContextFactory { public static DbContext DbContext { get { DbContext dbContext = CallContext.GetData("DbContext") as DbContext; if (dbContext == null) { dbContext = new ModelContainer(); CallContext.SetData("DbContext", dbContext); } return dbContext; } } } 接下來實(shí)現(xiàn)具體的實(shí)體數(shù)據(jù)訪問層,以UserInfoDal為例,其余類似。 public class UserInfoDal : BaseDal<UserInfo>, IUserInfoDal { }
首先像DAL層一樣,定義通用接口。 public interface IBaseService<T> where T : class,new() { void Add(T entity); void Delete(T entity); void Update(T entity); IQueryable<T> GetEntities(Expression<Func<T, bool>> expression); IQueryable<T> GetEntitiesByPage<TKey>(int pageSize, int pageIndex, bool isAsc, Expression<Func<T, TKey>> keySelector, Expression<Func<T, bool>> expression); bool SaveChanges(); } 通用基類,注意通用基類不需要實(shí)現(xiàn)上面的接口 public class BaseService<T> where T : class,new() { private BaseDal<T> baseDal = new BaseDal<T>(); public void Add(T entity) { baseDal.Add(entity); } public void Delete(T entity) { baseDal.Delete(entity); } public void Update(T entity) { baseDal.Update(entity); } public IQueryable<T> GetEntities(Expression<Func<T, bool>> expression) { return baseDal.GetEntities(expression); } public IQueryable<T> GetEntitiesByPage<TKey>(int pageSize, int pageIndex, bool isAsc, Expression<Func<T, TKey>> keySelector, Expression<Func<T, bool>> expression) { return baseDal.GetEntitiesByPage(pageSize, pageIndex, isAsc, keySelector, expression); } public bool SaveChanges() { return baseDal.SaveChanges(); } } 接下來是UserInfoService public class UserInfoService : BaseService<UserInfo>, IBaseService<UserInfo> { } 至此,所有底層代碼完成,頂層的UI層調(diào)用不在贅述了,這里附上源碼下載地址 鏈接:https://pan.baidu.com/s/1itW5XKBYB1onkQDfuwJvMw 說明:源碼中Model層中采用的ef的Model First方式創(chuàng)建數(shù)據(jù)庫,下載以后不能直接運(yùn)行,可以將Model程序集中的Model.edmx.sql在sqlserver創(chuàng)建數(shù)據(jù)庫,以DataBase First方式重新創(chuàng)建Model程序集,可以正常運(yùn)行。
|
|