返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期

第一点,上一篇文章中我们讲到codefirst中一些问题包括如图,codefirst在每次执行命令的时候会生成新的类,后来会越来越多。

1,codefirst在执行的数据库迁移过程中产生了很多文件,对于强迫症的我而言特别不爽,这些其实是可以不用生成的。

2,在codefirst实际开发过程的冲突

3,每次增加一个表或者增删改一个字段都要去敲命令,好麻烦

4,数据库初始化的时候,不用把很多东西写入程序里面。

5,其实有时候报错不好找错误的原因

6,对于存储过程的执行,可以放到脚本里面。

7,菜单初始化,管理员等基础配置可以放到脚本里面。

8,对于已经建好的表,需要修改吗,增加,删除字段的时候我们可以用存储过程处理。可以写在脚本里面、

9.索引可以写在脚本里面。

10,还有其他包含数据库定时执行业务逻辑的作业之类的等等其他特点。

针对这些我在这个项目采用了以前get到的一种方法--脚本的方法去处理数据库

第二点,abp module-zero里面的很多东西需要一定基础才能看懂,才能整明白,然后在新建项目的时候,我们并不希望而且不建议包含module-zero里面的内容.

针对以上我们到abp生成了下面的项目:

下面是我们生成包含module-zero的项目

在JCmsErp新生成的里面我们看到,在Application层和Core层少了很多关于zero的业务逻辑和模型,初次在生成对很多人会造成困扰.

此后我们以JCmsErp开始以后的项目.

1,修改数据连接

2,还原NuGet包

3,F5生成之后我们看到项目如下.

项目生成成功之后,一切准备就绪,.开始进入正题,数据库脚本.

首先我们看一下abp自带的连接数据库的数据库上下文

这里已经建好了自动获取数据库连接连接上方式的类

然后我们在它下面建一个获取数据库上下文的类ContextFactory,只是在ABP的基础上扩展出来的类。

里面获取上下文的类代码我已经写好.

   public class ContextFactory
{ /// <summary>
/// 获取当前数据上下文
/// </summary>
/// <returns></returns>
public static JCMSDbContext GetCurrentContext()
{
JCMSDbContext db = CallContext.GetData("Default") as JCMSDbContext;
if (db == null)
{
db = new JCMSDbContext();
CallContext.SetData("Default", db);
}
return db;
} public static void GetCurrentContextSetDatabaseExecuteSqlCommand(string FullName)
{
JCMSDbContext db = CallContext.GetData("Default") as JCMSDbContext;
db.Database.ExecuteSqlCommand(System.IO.File.ReadAllText(FullName, Encoding.Default));
}
}

为了做好准备工作,我们再在web目录下创建Data文件夹,在Data文件夹下建一个脚本Users

在脚本里面添加数据库脚本.

做好了这些,然后我们在去home控制器里面添加ActionResult InitDataBase 并且添加InitDataBase 试图,在InitDataBase 里面写好简单样式按钮.

此处为了方便,我引了bootstrap-3.2.0的样式和js,看下出来页面

什么,样子丑?样子丑就别管了,凑合凑合了...

注意上面按钮js执行的方法,指向控制器里面的方法,看下控制器的另一个方法,操作数据库的方法

CheckDatabase方法指向了连接数据库操作数据库的EntityFramework的方法,为了操作数据库,我在ContextFactory又添加了两个方法,看一下

然后点击InitDataBase页面的按钮,接下来就是见证奇迹的时刻了,奇迹就是本章的主题,根据脚本自动创建数据库了,来看下前后对面.

这里我已经把abp自带的数据库删除了,这是执行前的数据库。

执行后user数据库就已经根据脚本自动生成数据库了。

执行之后,我们创建表的语句就在数据库里面了.我们还可以在脚本里面写初始化需要的数据,

以后你会发现脚本有它强大的地方

1,初始化需要的管理员角色,

2,菜单

3,初始化需要的必须的数据

4,执行的存储过程

5,比如直接调用存储过程修改表的语句。

call proc_update_field('course','audiences','longtext default null','');
call proc_add_field('course', 'picFileId', 'varchar(36) default null', ' comment ''上传图片文件Id'' after `isAutoNo`');

6,比如索引的操作

drop procedure if exists del_idx;
create procedure del_idx(IN p_tablename varchar(), IN p_idxname varchar())
comment '删除索引'
begin
set @schema_name = database();
set @str=concat('drop index ',p_idxname,' on ', @schema_name, '.', p_tablename, ';');
select count(*) into @cnt from information_schema.statistics where TABLE_SCHEMA=@schema_name and table_name=p_tablename and index_name=p_idxname; if @cnt > then
call excuteproc(@str);
end if;
end ;

7,对于大型的数据我们直接通过脚本直接操作数据库,不必通过底层orm框架。当然也可以abp在原有的基础上扩展

至此,第二章关于数据库脚本就写完了,其实涉及到的代码很简单,就是简单的数据操作。重要的是这种思想和扩展。还有很多功能没有展示在项目里面,包括索引扫描的,其实都可以自己去试一试的。最近比较忙,都没时间去写。

需要的可以去下载源码看一下:  项目GitHub地址:https://github.com/Jimmey-Jiang/JCMS

附上数据库代码:

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE TABLE [dbo].[Users]
(
[Id] [INT] IDENTITY(1, 1)
NOT NULL ,
[UserName] [NVARCHAR](20) NOT NULL ,
[Password] [NVARCHAR](32) NOT NULL ,
[Email] [NVARCHAR](50) NOT NULL ,
[Phone] [NVARCHAR](50) NULL ,
[Address] [NVARCHAR](300) NULL ,
[UpdateDate] [DATETIME] NOT NULL ,
[TrueName] [NVARCHAR](20) NOT NULL ,
[Enabled] [BIT] NOT NULL ,
[CreationTime] [DATETIME] NULL ,
[IsDeleted] [BIT] NULL ,
[CreatorUserId] [NVARCHAR](20) NULL ,
[LastModificationTime] [DATETIME] NULL
)
ON [PRIMARY]; GO
SET IDENTITY_INSERT [dbo].[Users] ON; GO
INSERT [dbo].[Users]
( [id] ,
[UserName] ,
[Password] ,
[Email] ,
[Phone] ,
[Address] ,
[UpdateDate] ,
[TrueName] ,
[Enabled] ,
[CreationTime] ,
[IsDeleted] ,
[CreatorUserId] ,
[LastModificationTime]
)
VALUES ( 1 ,
N'admin' ,
N'' ,
N'2181130@qq.com' ,
N'' ,
N'深圳' ,
CAST(0x0000A7C000000000 AS DATETIME) ,
N'admin' ,
1 ,
CAST(0x0000A7C000000000 AS DATETIME) ,
0 ,
N'' ,
CAST(0x0000A7C000000000 AS DATETIME)
);
GO
SET IDENTITY_INSERT [dbo].[Users] OFF;
GO

InitDataBase页面代码:

@{
ViewBag.Title = "InitDataBase";
} <!DOCTYPE html>
<html>
<head>
<title>JCMS安装程序</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="~/Scripts/bootstrap-3.2.0/css/bootstrap.css" rel="stylesheet" />
<link href="~/Scripts/bootstrap-3.2.0/css/install.css" rel="stylesheet" />
</head>
<body>
<div class="install-container">
<div class="paper">
<div class="paper-heading">
<h1>
<span class="brand">JCMS</span> <span class="text-muted">安装向导</span>
</h1>
</div>
<div class="paper-body">
<div class="actions">
<button id="btnInit" class="btn btn-default">
初始化数据
</button>
<div id="info">
</div>
</div>
</div>
</div>
</div>
<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/jquery-2.1.4.min.js"></script>
<script src="~/Scripts/bootstrap.js"></script>
<script type="text/javascript">
$("#btnInit").click(function () {
$("#btnInit").attr("disabled", "disabled");
$("#btnInit").next().text("正在初始化数据......"); var btnInit = $("#btnInit").next();
var lbTip = $("#btnInit").next();
$.ajax({
url: '/Home/CheckDatabase',
success: function (data) {
if (data.success) {
// $.messager.alert('提示', '操作成功!请重启站点!');
window.location = "/Home/Login";
} else {
alert('操作失败!请查看日志!');
}
},
error: function () {
alert('初始化数据失败!');
},
complete: function () {
$.messager.progress('close');
}
});
});
</script>
</body>
</html>

HomeController代码:

       private JCMSDbContext db = ContextFactory.GetCurrentContext();

        [DisableAbpAntiForgeryTokenValidation]
[HttpGet]
[DontWrapResult]
public ActionResult Login()
{
return View();
} public ActionResult InitDataBase()
{
return View();
} //初始化
public JsonResult CheckDatabase()
{
// db.Users var success = true; List<FileInfo> list = new List<FileInfo>();
foreach (var item in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "Data"))
{
list.Add(new FileInfo(item));
}
var item0 = (from e in list where e.Name != "procedure.sql" select new { e.FullName, e.Name }).FirstOrDefault();
try
{ var items = from e in list where e.Name != "procedure.sql" && e.Name != "nv_folder.sql" && e.Name != "index.sql" && e.Extension == ".sql" select new { e.FullName, e.Name };
foreach (var item in items)
{
try
{
ContextFactory.GetCurrentContextSetDatabaseExecuteSqlCommand(item.FullName);
}
catch (Exception ex)
{
success = false;
Logger.Error("脚本" + item.Name + ":" + ex);
}
} }
catch (Exception ex)
{
success = false;
Logger.Error("脚本" + item0.Name + ":" + ex);
} return Json(new { success = success }, JsonRequestBehavior.AllowGet);
}

返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期

ABP+AdminLTE+Bootstrap Table权限管理系统第二节--在ABP的基础做数据库脚本处理的更多相关文章

  1. ABP+AdminLTE+Bootstrap Table权限管理系统第二节--数据库脚本

    第一点,上一篇文章中我们讲到codefirst中一些问题包括如图 1,codefirst在执行的数据库迁移过程中产生了很多文件,对于强迫症的我而言特别不爽,这些是可以不用生成的啊 2,在codefir ...

  2. ABP+AdminLTE+Bootstrap Table权限管理系统第九节--AdminLTE模板页搭建

    AdminLTE 官网地址:https://adminlte.io/themes/AdminLTE/index2.html 首先去官网下载包下来,然后引入项目. 然后我们在web层添加区域Admin以 ...

  3. ABP+AdminLTE+Bootstrap Table权限管理系统第九节--AdminLTE引入及模板页和布局和菜单

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 AdminLTE AdminLTE 官网地址:https://adminlte.io/themes/AdminLT ...

  4. ABP+AdminLTE+Bootstrap Table权限管理系统第一节--使用ASP.NET Boilerplate模板创建解决方案

    "abp是ASP.NET Boilerplate简称,是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板" abp官方网站: ...

  5. ABP+AdminLTE+Bootstrap Table权限管理系统一期

       学而时习之,不亦说乎,温顾温知新,可以为师矣. 这也是算是一种学习的方法和态度吧,经常去学习和总结,在博客园看了很多大神的文章,写下一点对于ABP(ABP是“ASP.NET Boilerplat ...

  6. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及abp封装的Javascript函数库

    经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这里算是前面几节的一个初次试水. 首先我们数据库已经有的相应的数据. 模型和DTO已经建好,所以我们直接在服务 ...

  7. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及几种abp封装的Javascript函数库

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期         简介 经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这 ...

  8. ABP+AdminLTE+Bootstrap Table权限管理系统第五节--WBEAPI及SwaggerUI

    一,Web API ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没 ...

  9. ABP+AdminLTE+Bootstrap Table权限管理系统第十节--AdminLTE模板菜单处理

    上节我们把布局页,也有的临时的菜单,但是菜单不是应该动态加载的么?,所以我们这节来写菜单.首先我们看一下AdminLTE源码里面的菜单以及结构. <aside class="main- ...

随机推荐

  1. 对称加密详解,以及JAVA简单实现

    (原) 常用的加密有3种 1.正向加密,如MD5,加密后密文固定,目前还没办法破解,但是可以能过数据库撞库有一定概率找到,不过现在一般用这种方式加密都会加上盐值. 2.对称加密,通过一个固定的对称密钥 ...

  2. Spark SQL笔记——技术点汇总

    目录 概述 原理 组成 执行流程 性能 API 应用程序模板 通用读写方法 RDD转为DataFrame Parquet文件数据源 JSON文件数据源 Hive数据源 数据库JDBC数据源 DataF ...

  3. tensorflow softsign函数应用

    1.softsign函数 图像 2.tensorflow softsign应用 import tensorflow as tf input=tf.constant([0,-1,2,-30,30],dt ...

  4. IDEA+Java:Selenium+Maven+TestNG基本WebUI自动化测试环境搭建

    IDEA+java:Selenium+Maven+TestNG 本文介绍的测试环境,应该是最基本的测试环境了,也是很多文章都有写,这里做一个完整的图文配置整理,方便阅读理解! 使用maven的好处,由 ...

  5. (转)log4j(二)——如何控制日志信息的输出?

    一:测试环境与log4j(一)——为什么要使用log4j?一样,这里不再重述 1 先看栗子再来下结论 import org.apache.log4j.*; import test.log4j.bean ...

  6. [Tyvj 1952] Easy

    P1952 Easy 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(我们来简化一下 ...

  7. Unity Shader入门精要读书笔记(一)序章

    本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...

  8. Swift学习之元组(Tuple)

    定义 元组是由若干个类型的数据组成,组成元组的数据叫做元素,每个元素的类型都可以是任意的. 用法一 let tuples1 = ("Hello", "World" ...

  9. ajax-jquery方法-初步入门01(整理)

    -----------------------------------2017.07.21写----------------------------------------- 相比较原生javascr ...

  10. Js 获取时间戳

    //获取时间戳 单位:秒: //1. 获取当前时间戳 function getUnixTime(){ var date = new Date(); //使用getTime方法: var unix_ti ...