ASP.NET MVC5+EF6+EasyUI 后台管理系统(59)-BLL层重构
系列目录
前言:
这应该是本系统最后一次重构,将重构BLL层和Model层。来完全取代代码生成器生成的BLL层和DAL层。完全废掉了代码生成器的DAL,BLL,MODEL层。
全自动生成增,删,改,查的通用方法和模型转换与BLL层的模型事务脱离,后续文章,会以一些插件或功能为目的,继续完善,进行分享,最后60节的文章会对本系统做一个总结
(但是还没时间写,相信60节的文章能让你快速了解到本系统的优势和架构,就算你从未阅读之前的所有文章)
继上次的DAL层重构(上一节),本来只想重构DAL层算了,但是鉴于本人是代码强迫症患者,所以花了些时间把BLL层重构。
在此务必共鸣一个问题,代码重构不是架构改变,这个系统的架构完全还是原来的接口多层注入架构!如下图所示完全不变
最后必须让初学者理解一个知识点:分部类 partial 关键字,因为我们的重构是围绕分部类而实现,包括接口
partial 关键字指示可在命名空间中定义该类、结构或接口的其他部分。所有部分都必须使用 partial 关键字。在编译时,各个部分都必须可用来形成最终的类型。各个部分必须具有相同的可访问性,如 public、private 等。
如果将任意部分声明为抽象的,则整个类型都被视为抽象的。如果将任意部分声明为密封的,则整个类型都被视为密封的。如果任意部分声明基类型,则整个类型都将继承该类。
指定基类的所有部分必须一致,但忽略基类的部分仍继承该基类型。各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用。最终类型是所有部分在编译时的组合。
下列声明:
partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }
等效于下列声明:
class Earth : Planet, IRotate, IRevolve { }
1.改变现状
相比我们DAL层,重构BLL层是有技术难度的,因为业务层涉及模型的转换构成,虽然只重构模块的(增、删、改、查),下面我们开始
下载上一节代码(https://yunpan.cn/cYUdjssbmiLrL 访问密码 e622)来分析业务层。
分析:IBLL,BLL
IBLL层不用说了,跟IDAL层是一致的
所以我们直接复制IDAL的TT模版修改后如下
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="../../Apps.Models/Common.ttinclude"#><#@
output extension=".cs"#>
<# const string inputFile = @"../../Apps.Models/DB.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
{
return string.Empty;
} WriteHeader(codeStringGenerator, fileManager); foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
fileManager.StartNewFile("I"+entity.Name + "BLL.cs");
#>
using System;
using Apps.Common;
using System.Collections.Generic;
using Apps.Models<#=entity.Name.IndexOf("_")>?"."+entity.Name.Substring(,entity.Name.IndexOf("_")):".Sys" #>;
namespace Apps.IBLL
{
public partial interface I<#=entity.Name #>BLL
{
List<<#=entity.Name #>Model> GetList(ref GridPager pager, string queryStr);
bool Create(ref ValidationErrors errors, <#=entity.Name #>Model model);
bool Delete(ref ValidationErrors errors, string id);
bool Delete(ref ValidationErrors errors, string[] deleteCollection);
bool Edit(ref ValidationErrors errors, <#=entity.Name #>Model model);
<#=entity.Name #>Model GetById(string id);
bool IsExists(string id);
}
<#
EndNamespace(code); } fileManager.Process(); #>
ICommonBLL.tt
非常好。业务层完成跟预期是一样的!这样我们直接可以看到我们原来的ISysSample可以由
using System.Collections.Generic;
using Apps.Common;
using Apps.Models.Sys;
namespace Apps.IBLL
{ public interface ISysSampleBLL
{
List<SysSampleModel> GetList(ref GridPager pager, string queryStr);
bool Create(ref ValidationErrors errors, SysSampleModel model);
bool Delete(ref ValidationErrors errors, string id);
bool Delete(ref ValidationErrors errors, string[] deleteCollection);
bool Edit(ref ValidationErrors errors, SysSampleModel model);
SysSampleModel GetById(string id);
bool IsExist(string id);
}
}
变为--->
using System.Collections.Generic;
using Apps.Common;
using Apps.Models.Sys;
namespace Apps.IBLL
{
public partial interface ISysSampleBLL
{ }
}
代码行数发生质的改变,可以我们就可以扩展自己的接口方法,利用partial类
照样画葫芦,业务层也生成
直接上TT代码
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="../../Apps.Models/Common.ttinclude"#><#@
output extension=".cs"#>
<#
const string usingName = "";
const string inputFile = @"../../Apps.Models/DB.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
{
return string.Empty;
} WriteHeader(codeStringGenerator, fileManager); foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
if(entity.Name.StartsWith("Sys") || entity.Name.StartsWith("JOB"))
{
fileManager.StartNewFile(""+entity.Name + "BLL.cs");
var simpleProperties = typeMapper.GetSimpleProperties(entity);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using Apps.Models;
using Apps.Common;
using Microsoft.Practices.Unity;
using System.Transactions;
using Apps.IBLL;
using Apps.IDAL;
using Apps.BLL.Core;
using Apps.Locale;
using Apps.Models<#=entity.Name.IndexOf("_")>?"."+entity.Name.Substring(,entity.Name.IndexOf("_")):".Sys" #>;
namespace Apps.BLL
{
public partial class <#=entity.Name #>BLL:I<#=entity.Name #>BLL
{
[Dependency]
public I<#=entity.Name #>Repository m_Rep { get; set; } public virtual List<<#=entity.Name #>Model> GetList(ref GridPager pager, string queryStr)
{ IQueryable<<#=entity.Name #>> queryData = null;
if (!string.IsNullOrWhiteSpace(queryStr))
{
queryData = m_Rep.GetList(
<#
int i =;
if (simpleProperties.Any()){foreach(var edmProperty in simpleProperties){
if(i==)
{ #>
<#=codeStringGenerator.Property(edmProperty).ToString().IndexOf("string")>?"a=>a."+edmProperty+".Contains(queryStr)":""#>
<#
if(codeStringGenerator.Property(edmProperty).ToString().IndexOf("string")>)
{
i=;
}
}
else if(i==)
{#>
<#=codeStringGenerator.Property(edmProperty).ToString().IndexOf("string")>?"|| a."+edmProperty+".Contains(queryStr)":""#>
<#
} #>
<#} }#>
);
}
else
{
queryData = m_Rep.GetList();
}
pager.totalRows = queryData.Count();
//排序
queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
return CreateModelList(ref queryData);
}
public virtual List<<#=entity.Name #>Model> CreateModelList(ref IQueryable<<#=entity.Name #>> queryData)
{ List<<#=entity.Name #>Model> modelList = (from r in queryData
select new <#=entity.Name #>Model
{
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
<#=edmProperty#> = r.<#=edmProperty#>,
<#
}
}
#>
}).ToList(); return modelList;
} public virtual bool Create(ref ValidationErrors errors, <#=entity.Name #>Model model)
{
try
{
<#=entity.Name #> entity = m_Rep.GetById(model.Id);
if (entity != null)
{
errors.Add(Resource.PrimaryRepeat);
return false;
}
entity = new <#=entity.Name #>();
<# if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
entity.<#=edmProperty#> = model.<#=edmProperty#>;
<#
}
}
#> if (m_Rep.Create(entity))
{
return true;
}
else
{
errors.Add(Resource.InsertFail);
return false;
}
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual bool Delete(ref ValidationErrors errors, string id)
{
try
{
if (m_Rep.Delete(id) == )
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual bool Delete(ref ValidationErrors errors, string[] deleteCollection)
{
try
{
if (deleteCollection != null)
{
using (TransactionScope transactionScope = new TransactionScope())
{
if (m_Rep.Delete(deleteCollection) == deleteCollection.Length)
{
transactionScope.Complete();
return true;
}
else
{
Transaction.Current.Rollback();
return false;
}
}
}
return false;
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual bool Edit(ref ValidationErrors errors, <#=entity.Name #>Model model)
{
try
{
<#=entity.Name #> entity = m_Rep.GetById(model.Id);
if (entity == null)
{
errors.Add(Resource.Disable);
return false;
}
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
entity.<#=edmProperty#> = model.<#=edmProperty#>;
<#
}
}
#> if (m_Rep.Edit(entity))
{
return true;
}
else
{
errors.Add("没有数据改变");
return false;
} }
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual <#=entity.Name #>Model GetById(string id)
{
if (IsExists(id))
{
<#=entity.Name #> entity = m_Rep.GetById(id);
<#=entity.Name #>Model model = new <#=entity.Name #>Model();
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
model.<#=edmProperty#> = entity.<#=edmProperty#>;
<#
}
}
#>
return model;
}
else
{
return null;
}
} public virtual bool IsExists(string id)
{
return m_Rep.IsExist(id);
}
public void Dispose()
{ } }
<#
EndNamespace(code);
}
} fileManager.Process(); #>
CommonBLL.tt
由于每一个业务模型的属性都不一致,这里不能用List<T>来做,所以,一个表会生成一个BLL类。(图中红色部分)
如果生成红色部分。主要看下面代码
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
<#=edmProperty#> = r.<#=edmProperty#>,
<#
}
}
#>
获取表模型的所有属性,所有这段对很多人是有帮助的,请收藏,说不定你以后要用到
OK,编译通过,运行正确,还是熟悉的面孔
但是至此。我们的业务层和数据访问层,可以说是一行代码都没写。足够体现了TT模版的强大之处,相比我们之前要用代码生成器来得极其方便
2.引发问题
直到上面步骤,一切都很顺利,没有一点不妥。
有经验的园友会发现,里面东西都是写死的。而且分部类不可以重写自己。
比如说。我在处理 entity.Name = model.Name;时候我想entity.Name = model.Name.TrimStart() 去掉字符串前面的空格,那么可以看到根本无法操作。
然而我们需要重写,但是又发现无法重写分部类的方法,怎么做?必须用一张图来看,我是这么做的
- 绿色是我们已经重构完成的。
- 紫色是我们需要重构的一个TT模版,这是所有都是虚方法的类
- 粉色是我们自己扩张的业务方法,目前为空
虚方法是可以重写的关键字是virtual 以下重写之后优先级高于前者 用override。用代码来说明
改变一下CommonBLL.tt
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="../../Apps.Models/Common.ttinclude"#><#@
output extension=".cs"#>
<#
const string usingName = "";
const string inputFile = @"../../Apps.Models/DB.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
{
return string.Empty;
} WriteHeader(codeStringGenerator, fileManager); foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
if(entity.Name.StartsWith("Sys") || entity.Name.StartsWith("JOB"))
{
fileManager.StartNewFile("Virtual_"+entity.Name + "BLL.cs");
var simpleProperties = typeMapper.GetSimpleProperties(entity);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using Apps.Models;
using Apps.Common;
using Microsoft.Practices.Unity;
using System.Transactions;
using Apps.IBLL;
using Apps.IDAL;
using Apps.BLL.Core;
using Apps.Locale;
using Apps.Models<#=entity.Name.IndexOf("_")>?"."+entity.Name.Substring(,entity.Name.IndexOf("_")):".Sys" #>;
namespace Apps.BLL
{
public class Virtual_<#=entity.Name #>BLL
{
[Dependency]
public I<#=entity.Name #>Repository m_Rep { get; set; } public virtual List<<#=entity.Name #>Model> GetList(ref GridPager pager, string queryStr)
{ IQueryable<<#=entity.Name #>> queryData = null;
if (!string.IsNullOrWhiteSpace(queryStr))
{
queryData = m_Rep.GetList(
<#
int i =;
if (simpleProperties.Any()){foreach(var edmProperty in simpleProperties){
if(i==)
{ #>
<#=codeStringGenerator.Property(edmProperty).ToString().IndexOf("string")>?"a=>a."+edmProperty+".Contains(queryStr)":""#>
<#
if(codeStringGenerator.Property(edmProperty).ToString().IndexOf("string")>)
{
i=;
}
}
else if(i==)
{#>
<#=codeStringGenerator.Property(edmProperty).ToString().IndexOf("string")>?"|| a."+edmProperty+".Contains(queryStr)":""#>
<#
} #>
<#} }#>
);
}
else
{
queryData = m_Rep.GetList();
}
pager.totalRows = queryData.Count();
//排序
queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
return CreateModelList(ref queryData);
}
public virtual List<<#=entity.Name #>Model> CreateModelList(ref IQueryable<<#=entity.Name #>> queryData)
{ List<<#=entity.Name #>Model> modelList = (from r in queryData
select new <#=entity.Name #>Model
{
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
<#=edmProperty#> = r.<#=edmProperty#>,
<#
}
}
#>
}).ToList(); return modelList;
} public virtual bool Create(ref ValidationErrors errors, <#=entity.Name #>Model model)
{
try
{
<#=entity.Name #> entity = m_Rep.GetById(model.Id);
if (entity != null)
{
errors.Add(Resource.PrimaryRepeat);
return false;
}
entity = new <#=entity.Name #>();
<# if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
entity.<#=edmProperty#> = model.<#=edmProperty#>;
<#
}
}
#> if (m_Rep.Create(entity))
{
return true;
}
else
{
errors.Add(Resource.InsertFail);
return false;
}
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual bool Delete(ref ValidationErrors errors, string id)
{
try
{
if (m_Rep.Delete(id) == )
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual bool Delete(ref ValidationErrors errors, string[] deleteCollection)
{
try
{
if (deleteCollection != null)
{
using (TransactionScope transactionScope = new TransactionScope())
{
if (m_Rep.Delete(deleteCollection) == deleteCollection.Length)
{
transactionScope.Complete();
return true;
}
else
{
Transaction.Current.Rollback();
return false;
}
}
}
return false;
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual bool Edit(ref ValidationErrors errors, <#=entity.Name #>Model model)
{
try
{
<#=entity.Name #> entity = m_Rep.GetById(model.Id);
if (entity == null)
{
errors.Add(Resource.Disable);
return false;
}
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
entity.<#=edmProperty#> = model.<#=edmProperty#>;
<#
}
}
#> if (m_Rep.Edit(entity))
{
return true;
}
else
{
errors.Add(Resource.NoDataChange);
return false;
} }
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
} public virtual <#=entity.Name #>Model GetById(string id)
{
if (IsExists(id))
{
<#=entity.Name #> entity = m_Rep.GetById(id);
<#=entity.Name #>Model model = new <#=entity.Name #>Model();
<#
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
model.<#=edmProperty#> = entity.<#=edmProperty#>;
<#
}
}
#>
return model;
}
else
{
return null;
}
} public virtual bool IsExists(string id)
{
return m_Rep.IsExist(id);
}
public void Dispose()
{ } }
<#
EndNamespace(code);
}
} fileManager.Process(); #>
VirtualBLL.tt
更Common代码基本一致,只是头部变了,文件名称变了
public class Virtual_SysSampleBLL
那么重新创建一个CommonBLL.tt
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="../../Apps.Models/Common.ttinclude"#><#@
output extension=".cs"#>
<#
const string usingName = "";
const string inputFile = @"../../Apps.Models/DB.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
{
return string.Empty;
} WriteHeader(codeStringGenerator, fileManager); foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
if(entity.Name.StartsWith("Sys") || entity.Name.StartsWith("JOB"))
{
fileManager.StartNewFile(entity.Name + "BLL.cs");
var simpleProperties = typeMapper.GetSimpleProperties(entity);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using Apps.Models;
using Apps.Common;
using Microsoft.Practices.Unity;
using System.Transactions;
using Apps.IBLL;
using Apps.IDAL;
using Apps.BLL.Core;
using Apps.Locale;
using Apps.Models<#=entity.Name.IndexOf("_")>?"."+entity.Name.Substring(,entity.Name.IndexOf("_")):".Sys" #>;
namespace Apps.BLL
{
public partial class <#=entity.Name #>BLL: Virtual_<#=entity.Name #>BLL,I<#=entity.Name #>BLL
{ }
<#
EndNamespace(code);
}
} fileManager.Process(); #>
CommonBLL.tt
代码生成后如下,什么都没有实现继承接口,和上面的TT模版的类
namespace Apps.BLL
{
public partial class SysSampleBLL: Virtual_SysSampleBLL,ISysSampleBLL
{
}
}
好吧,我只是想省掉写: Virtual_SysSampleBLL,ISysSampleBLL
OK,运行之后还是熟悉的面孔,但是可以重载了,我们重载一下,好处理我们的业务!
新建SysSampleBLL.cs
namespace Apps.BLL
{
public partial class SysSampleBLL
{
public override bool Create(ref ValidationErrors errors, SysSampleModel model)
{
try
{
SysSample entity = m_Rep.GetById(model.Id);
if (entity != null)
{
errors.Add(Resource.PrimaryRepeat);
return false;
}
entity = new SysSample();
entity.Id = model.Id;
entity.Name = model.Name.TrimStart();
entity.Age = model.Age;
entity.Bir = model.Bir;
entity.Photo = model.Photo;
entity.Note = model.Note;
entity.CreateTime = model.CreateTime;
if (m_Rep.Create(entity))
{
return true;
}
else
{
errors.Add(Resource.InsertFail);
return false;
}
}
catch (Exception ex)
{
errors.Add(ex.Message);
ExceptionHander.WriteException(ex);
return false;
}
}
}
}
同样的。我们可以对Model层进行重构,类似BLL层。利用虚属性,可以对属性进行注解。来获得优先级,和一次生成编译通过
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码已从模板生成。
//
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,将覆盖对此文件的手动更改。
// </auto-generated>
//------------------------------------------------------------------------------ using Apps.Models;
using System;
namespace Apps.Models.Sys
{
public class Virtual_SysSampleModel
{
public virtual string Id { get; set; }
public virtual string Name { get; set; }
public virtual Nullable<int> Age { get; set; }
public virtual Nullable<System.DateTime> Bir { get; set; }
public virtual string Photo { get; set; }
public virtual string Note { get; set; }
public virtual Nullable<System.DateTime> CreateTime { get; set; }
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码已从模板生成。
//
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,将覆盖对此文件的手动更改。
// </auto-generated>
//------------------------------------------------------------------------------ using Apps.Models;
using System;
namespace Apps.Models.Sys
{
public partial class SysSampleModel:Virtual_SysSampleModel
{ }
}
然后自己建Model对其重载
-------------------------------------------------------------------丑陋的分割线----------------------------------------------------------------------------------------
到此,我们重构了DAL层和BLL层。对比原来的代码生成器方式。我们新建一个表不用再生成DAL层和BLL层的代码。直达界面
利用代码生成器获得控制器和View视图。直接得到界面。一个字爽。大家可以下载代码来研究
代码生成器在第一节下载,但是代码生成器本人很久没有维护,可能生成的index.cshtml会有一些问题,但是好很好解决。自己花点时间来设计成自己的前端生成器。
OK、本文到此结束,谢谢
ASP.NET MVC5+EF6+EasyUI 后台管理系统(59)-BLL层重构的更多相关文章
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 任务调度系统界面 http: ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理 http://ww ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入
系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试
1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级
系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构
系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析
系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控
系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox
系列目录 https://yunpan.cn/cZVeSJ33XSHKZ 访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(29)-T4模版
系列目录 本节不再适合本系统,在58,59节已经重构.请超过本节 这讲适合所有的MVC程序 很荣幸,我们的系统有了体验的地址了.演示地址 之前我们发布了一个简单的代码生成器,其原理就是读取数据库的表结 ...
随机推荐
- 【.net 深呼吸】细说CodeDom(1):结构大观
CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...
- Fis3的前端工程化之路[三大特性篇之内容嵌入]
Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
最新的Mono 4.4已经支持运行asp.net mvc5项目,有的同学听了这句话就兴高采烈的拿起Visual Studio 2015创建了一个mvc 5的项目,然后部署到Mono上,浏览下发现一堆错 ...
- 06.SQLServer性能优化之---数据库级日记监控
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 之前说了一下数据库怎么发邮件:http://www.cnblogs.com/duniti ...
- C#多线程之线程同步篇3
在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...
- 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范
昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...
- MongoDB系列(二):C#应用
前言 上一篇文章<MongoDB系列(一):简介及安装>已经介绍了MongoDB以及其在window环境下的安装,这篇文章主要讲讲如何用C#来与MongoDB进行通讯.再次强调一下,我使用 ...
- RabbitMQ + PHP (三)案例演示
今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...
- nginx启动报错:/usr/local/nginx/sbin/nginx: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
查看依赖库:
- jexus5.8.2 linux x64专业版 配置https
一.环境 1.jexus版本:Jexus/5.8.2.8 Linux专业版 内置mono版本:Mono/4.6.2.7 2.操作系统:centOs7 jexus独立版由于是免安装版并且内置mono,所 ...