我在博客園潛水兩三年了,在這裏看過不少大神的文章,也學到了不少東西。能夠說我是汲取着博客園的養分成長的。前端
想當年,我也是拿10個G的精神糧食從一個博客園大神那裏換來一套開發框架,正式走上開發之路,到後來成爲主力開發,再到項目經理再後來順利拿下美工妹,也算是走上人生巔峯。jquery
只索取,不分享就是自私,你們都這麼自私還怎麼作技術交流,說到分享首先想到的就是我那120G的精神糧食,可是分享這個好像有點法律風險,因此我把這幾年在.net開發生涯中積累的一套框架分享給你們。數據庫
早上發過一篇博客,一下子就讓管理員拿掉了,這裏我解釋下徹底沒有廣告推廣的意思,我不會放置任何推廣信息,沒那個必要,房子、車子、妹子都有了,在一家還不錯的單位上着班,否則也沒這個閒心來作什麼開源框架,目的是有,就是出來在新手面前裝個逼。這樣吧你們下了代碼去看,裏面若是有一點點廣告嫌疑做者我小JJ自動縮短一釐米。後端
廢話少說,先來介紹下這個開發框架。緩存
框架名稱:NFine.Framwork,牛逼框架,好框架安全
框架使用場景:OA、ERP、BPM、CRM、WMS、TMS、MIS等業務管理系統及後臺系統app
一、NFine.Code 底層核心類(開發時不涉及,可編繹成dll提供)。echarts
二、NFine.Data 數據層(開發時不涉及,可編繹成dll提供)。框架
三、NFine.Application 應用(有點相似業務邏輯層) 編輯器
四、NFine.Domain 領域層。
五、NFine.Mapping 數據庫映射。
六、NFine.Repository 數據訪問。
七、NFine.Web 前端視圖及控制器。
一、前端技術
JS框架:jquery-2.1.一、Bootstrap.js、JQuery UI
CSS框架:Bootstrap v3.3.4(穩定是後臺,UI方面根據需求本身升級改造吧)。
客戶端驗證:jQuery Validation Plugin 1.9.0。
在線編輯器:ckeditor、simditor
上傳文件:Uploadify v3.2.1
動態頁籤:Jerichotab(本身改造)
數據表格:jqGrid、Bootstrap Talbe
對話框:layer-v2.3
下拉選擇框:jQuery Select2
樹結構控件:jQuery zTree、jQuery wdtree
頁面佈局:jquery.layout.js 1.4.4
圖表插件:echarts、highcharts
日期控件: My97DatePicker
二、後端技術
核心框架:ASP.NET MVC五、WEB API
持久層框架:EntityFramework 6.0
定時計劃任務:Quartz.Net組件
安全支持:過濾器、Sql注入、請求僞造
服務端驗證:實體模型驗證、本身封裝Validator
緩存框架:微軟自帶Cache、Redis
日誌管理:Log4net、登陸日誌、操做日誌
工具類:NPOI、Newtonsoft.Json、驗證碼、豐富公共相似
數據庫、倉庫代碼
1 using NFine.Code; 2 using System; 3 using System.Collections.Generic; 4 using System.Data.Common; 5 using System.Linq; 6 using System.Linq.Expressions; 7 8 namespace NFine.Data 9 { 10 /// <summary> 11 /// 倉儲接口 12 /// </summary> 13 /// <typeparam name="TEntity">實體類型</typeparam> 14 public interface IRepositoryBase<TEntity> where TEntity : class,new() 15 { 16 int Insert(TEntity entity); 17 int Insert(List<TEntity> entitys); 18 int Update(TEntity entity); 19 int Delete(TEntity entity); 20 int Delete(Expression<Func<TEntity, bool>> predicate); 21 TEntity FindEntity(object keyValue); 22 TEntity FindEntity(Expression<Func<TEntity, bool>> predicate); 23 IQueryable<TEntity> IQueryable(); 24 IQueryable<TEntity> IQueryable(Expression<Func<TEntity, bool>> predicate); 25 List<TEntity> FindList(string strSql); 26 List<TEntity> FindList(string strSql, DbParameter[] dbParameter); 27 List<TEntity> FindList(Pagination pagination); 28 List<TEntity> FindList(Expression<Func<TEntity, bool>> predicate, Pagination pagination); 29 } 30 }
using NFine.Code; using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text.RegularExpressions; namespace NFine.Data { /// <summary> /// 倉儲實現 /// </summary> /// <typeparam name="TEntity"></typeparam> public class RepositoryBase<TEntity> : IRepositoryBase<TEntity> where TEntity : class,new() { public NFineDbContext dbcontext = new NFineDbContext(); public int Insert(TEntity entity) { dbcontext.Entry<TEntity>(entity).State = EntityState.Added; return dbcontext.SaveChanges(); } public int Insert(List<TEntity> entitys) { foreach (var entity in entitys) { dbcontext.Entry<TEntity>(entity).State = EntityState.Added; } return dbcontext.SaveChanges(); } public int Update(TEntity entity) { dbcontext.Set<TEntity>().Attach(entity); PropertyInfo[] props = entity.GetType().GetProperties(); foreach (PropertyInfo prop in props) { if (prop.GetValue(entity, null) != null) { if (prop.GetValue(entity, null).ToString() == " ") dbcontext.Entry(entity).Property(prop.Name).CurrentValue = null; dbcontext.Entry(entity).Property(prop.Name).IsModified = true; } } return dbcontext.SaveChanges(); } public int Delete(TEntity entity) { dbcontext.Set<TEntity>().Attach(entity); dbcontext.Entry<TEntity>(entity).State = EntityState.Deleted; return dbcontext.SaveChanges(); } public int Delete(Expression<Func<TEntity, bool>> predicate) { var entitys = dbcontext.Set<TEntity>().Where(predicate).ToList(); entitys.ForEach(m => dbcontext.Entry<TEntity>(m).State = EntityState.Deleted); return dbcontext.SaveChanges(); } public TEntity FindEntity(object keyValue) { return dbcontext.Set<TEntity>().Find(keyValue); } public TEntity FindEntity(Expression<Func<TEntity, bool>> predicate) { return dbcontext.Set<TEntity>().FirstOrDefault(predicate); } public IQueryable<TEntity> IQueryable() { return dbcontext.Set<TEntity>(); } public IQueryable<TEntity> IQueryable(Expression<Func<TEntity, bool>> predicate) { return dbcontext.Set<TEntity>().Where(predicate); } public List<TEntity> FindList(string strSql) { return dbcontext.Database.SqlQuery<TEntity>(strSql).ToList<TEntity>(); } public List<TEntity> FindList(string strSql, DbParameter[] dbParameter) { return dbcontext.Database.SqlQuery<TEntity>(strSql, dbParameter).ToList<TEntity>(); } public List<TEntity> FindList(Pagination pagination) { bool isAsc = pagination.sord.ToLower() == "asc" ? true : false; string[] _order = pagination.sidx.Split(','); MethodCallExpression resultExp = null; var tempData = dbcontext.Set<TEntity>().AsQueryable(); foreach (string item in _order) { string _orderPart = item; _orderPart = Regex.Replace(_orderPart, @"\s+", " "); string[] _orderArry = _orderPart.Split(' '); string _orderField = _orderArry[0]; bool sort = isAsc; if (_orderArry.Length == 2) { isAsc = _orderArry[1].ToUpper() == "ASC" ? true : false; } var parameter = Expression.Parameter(typeof(TEntity), "t"); var property = typeof(TEntity).GetProperty(_orderField); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExp = Expression.Lambda(propertyAccess, parameter); resultExp = Expression.Call(typeof(Queryable), isAsc ? "OrderBy" : "OrderByDescending", new Type[] { typeof(TEntity), property.PropertyType }, tempData.Expression, Expression.Quote(orderByExp)); } tempData = tempData.Provider.CreateQuery<TEntity>(resultExp); pagination.records = tempData.Count(); tempData = tempData.Skip<TEntity>(pagination.rows * (pagination.page - 1)).Take<TEntity>(pagination.rows).AsQueryable(); return tempData.ToList(); } public List<TEntity> FindList(Expression<Func<TEntity, bool>> predicate, Pagination pagination) { bool isAsc = pagination.sord.ToLower() == "asc" ? true : false; string[] _order = pagination.sidx.Split(','); MethodCallExpression resultExp = null; var tempData = dbcontext.Set<TEntity>().Where(predicate); foreach (string item in _order) { string _orderPart = item; _orderPart = Regex.Replace(_orderPart, @"\s+", " "); string[] _orderArry = _orderPart.Split(' '); string _orderField = _orderArry[0]; bool sort = isAsc; if (_orderArry.Length == 2) { isAsc = _orderArry[1].ToUpper() == "ASC" ? true : false; } var parameter = Expression.Parameter(typeof(TEntity), "t"); var property = typeof(TEntity).GetProperty(_orderField); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExp = Expression.Lambda(propertyAccess, parameter); resultExp = Expression.Call(typeof(Queryable), isAsc ? "OrderBy" : "OrderByDescending", new Type[] { typeof(TEntity), property.PropertyType }, tempData.Expression, Expression.Quote(orderByExp)); } tempData = tempData.Provider.CreateQuery<TEntity>(resultExp); pagination.records = tempData.Count(); tempData = tempData.Skip<TEntity>(pagination.rows * (pagination.page - 1)).Take<TEntity>(pagination.rows).AsQueryable(); return tempData.ToList(); } } }
自動映射對象實體
支持多皮膚切換
1:本文並無詳細講解實現機制。
2:本文並無詳細講解開發方式。
但,至少你能夠:看源碼、看API、看Demo,還能夠加入技術交流羣進行交流分享。
固然,後續我會補充相關文章,更加細化和完善的機制及開發方式。