系列目录

前言:

    这应该是本系统最后一次重构,将重构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() 去掉字符串前面的空格,那么可以看到根本无法操作。

然而我们需要重写,但是又发现无法重写分部类的方法,怎么做?必须用一张图来看,我是这么做的

  1. 绿色是我们已经重构完成的。
  2. 紫色是我们需要重构的一个TT模版,这是所有都是虚方法的类
  3. 粉色是我们自己扩张的业务方法,目前为空

虚方法是可以重写的关键字是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层重构的更多相关文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理   http://ww ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入

    系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试

    1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级

    系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构

    系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析

    系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控

    系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox

    系列目录 https://yunpan.cn/cZVeSJ33XSHKZ  访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(29)-T4模版

    系列目录 本节不再适合本系统,在58,59节已经重构.请超过本节 这讲适合所有的MVC程序 很荣幸,我们的系统有了体验的地址了.演示地址 之前我们发布了一个简单的代码生成器,其原理就是读取数据库的表结 ...

随机推荐

  1. nohup程序后台执行

    Linux常用命令,用于不挂断的执行程序. nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令.该命令可以在你退出帐户/关闭终端之后继续运行相应 ...

  2. 用MongoDB分析合肥餐饮业

    看了<从数据角度解析福州美食>后难免心痒,动了要分析合肥餐饮业的念头,因此特地写了Node.js爬虫爬取了合肥的大众点评数据.分析数据库我并没有采用MySQL而是用的MongoDB,是因为 ...

  3. 封装集合(Encapsulate Collection)

    封装就是将相关的方法或者属性抽象成为一个对象. 封装的意义: 对外隐藏内部实现,接口不变,内部实现自由修改. 只返回需要的数据和方法. 提供一种方式防止数据被修改. 更好的代码复用. 当一个类的属性类 ...

  4. Java程序员应该了解的10个面向对象设计原则

    面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...

  5. “风投云涌”:那些被资本看中的IT企业的风光与辛酸

         进入七月份以来,纷享销客获得D轮融资1亿美元,撼动业界,资本与IT联姻令一部分创业者眼红的同时,没有人注意到背后的风险. 科技与资本的结合,是当今经济社会前行的宏大主题.相关统计显示,软件行 ...

  6. android绘制圆形图片的两种方式

    看下效果先 下面有完整的示例代码 使用BitmapShader(着色器) 我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap ...

  7. swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明

    关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...

  8. PHP 数组浅析

    PHP的数组具有如下特点:1.数组初始化时无需指定长度:2.数组中的元素无需相同类型:3.数组的长度可变4.可使用var_dump(参数)或者print_r(  参数) 函数查看数组变量.5.数组内的 ...

  9. XSS 前端防火墙 —— 可疑模块拦截

    上一篇介绍的系统,已能预警现实中的大多数 XSS 攻击,但想绕过还是很容易的. 由于是在前端防护,策略配置都能在源代码里找到,因此很快就能试出破解方案.并且攻击者可以屏蔽日志接口,在自己电脑上永不发出 ...

  10. 深入浅出聊优化:从Draw Calls到GC

    前言: 刚开始写这篇文章的时候选了一个很土的题目...<Unity3D优化全解析>.因为这是一篇临时起意才写的文章,而且陈述的都是既有的事实,因而给自己“文(dou)学(bi)”加工留下的 ...