LINQ新增之多表新增
开发工具与关键技术:Visual Studio 2015 LINQ
作者:孙水兵
撰写时间:2019年4月12
一、 新增前期工作:
在控制器最上端引入Models和装实体类的文件名称
实例化Models
在控制器的命名空间中实例化Models
Models.CQUPTEntities 自定义名称 = new Models.CQUPTEntities();
二、 分析
目的:将页面传过来的学生数据新增入数据库中
思路:获取数据并传入控制器中——>判断数据——>判断数据是否与数据库中的重复——>新增表格——>新增成功
注意:
- 用表对象接收传递过来的表中的值的name要跟数据库中表的列名一致否则会传递不了数据
- 新增表格的顺序:由下面表格的照片可知,在学生表、用户表、用户角色明细表中都存在用户ID,若新增学生表或用户角色明细表,可能导致其中的用户ID为null,因此,表格新增的顺序为:用户表->学生表->用户角色明细表(其中学生表和用户角色明细表新增顺序可以互换)
- 由于表格的特殊,用户的账号和密码均为学生的学号
- 新增的用户类型均为学生,而且在数据库中学生的用户类型ID(UserTypeID)为6,因此在新增用户角色明细表中的用户类型时,将用户类型ID赋值为6
涉及表格:学生表(PW_Student)、用户表(PW_User)、用户角色明细表(PW_UserRoleDetail)
三、 开始新增
HTML部分(显示部分代码)与单表中的HTML类似(详情请见LINQ新增之单表新增),需注意
- input标签中的name要与数据库中表的列名(name)一致,方便控制器接收数据。
- 由于下面用到ajaxSubmit(obj)来提交数据,因此,在from表单中的from标签中,加入action,用来写表单提交路径(控制器中新增的路径)
- from标签中的id要与下方用ajaxSubmit()提交表单时用到的id一致,否则控制器接收不到数据
@*新增考生模态窗体*@
<div class="modal fade" id="modInsertExaminee">
<div class="modal-dialog modal-lg">
<div class="modal-content">
@*模态框头部*@
<div class="modal-header">
<h5 class="modal-title">考生录入</h5>
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
</div>
@*模态框内容*@
<div class="modal-body">
<form class="form-horizontal row" role="form" id="formInsertExaminee" action="/ExaminationManagement/SetExaminee/InsertStudent" method="post">
<div class="col-12 col-lg-9 row p-0 m-0">
<div class="col-12 col-lg-6 p-2 mb-0">
<div class="form-group form-row">
<label class="col-form-label col-lg-3">身份证号:</label>
<div class="col-lg-9">
<input type="text" class="form-control" id="IsStudentIDNum" name="StudentIDNum" autocomplete="off" />
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">考生学号:</label>
<div class="col-lg-9">
<input type="text" class="form-control" id="IsStudentNumber" name="StudentNumber" />
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">认证码:</label>
<div class="col-lg-9">
<input type="text" class="form-control" id="IsUniformAuthenticationCode" name="UniformAuthenticationCode" />
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">考生姓名:</label>
<div class="col-lg-9">
<input type="text" class="form-control" id="IsStudentName" name="StudentName" />
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">考生性别:</label>
<div class="col-lg-9">
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" name="StudentSex" id="IsStudentSexMale" class="custom-control-input" value="男" checked />
<label class="custom-control-label" for="IsStudentSexMale">男</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" name="StudentSex" id="IsStudentSexFemale" class="custom-control-input" value="女" />
<label class="custom-control-label" for="IsStudentSexFemale">女</label>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 p-2">
<div class="form-group form-row">
<label class="col-form-label col-lg-3">所在学院:</label>
<div class="col-lg-9">
<select class="form-control" id="IsAcademe" name="AcademeID"></select>
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">所在专业:</label>
<div class="col-lg-9">
<select class="form-control" id="IsSpecialty" name="SpecialtyID"></select>
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">所在年级:</label>
<div class="col-lg-9">
<select class="form-control" id="IsGrade" name="GradeID"></select>
</div>
</div>
<div class="form-group form-row">
<label class="col-form-label col-lg-3">所在班级:</label>
<div class="col-lg-9">
<select class="form-control" id="IsClass" name="ClassID"></select>
</div>
</div>
<div class="form-group form-row justify-content-center">
<div class="col-auto">
<button type="reset" class="btn btn-sm btn-primary">重置</button>
<button type="button" class="btn btn-sm btn-primary" "saveInsertModel()">保存</button>
<button type="button" class="btn btn-sm btn-danger" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
JS部分
与单表的类似,先获取页面数据,然后判断数据的完整性。稍微不同的是由于提交时的数据过多,用post提交会更麻烦,因此表单的提交方式发生改变,由post提交改为ajaxSubmit()提交(post提交详情请见LINQ新增之单表新增)
ajaxSubmit()提交表单:
我们直接通过form提交的话,提交后当前页面跳转到form的action所指向的页面。然而,很多时候我们并不希望提交表单后页面跳转,那么,我们就可以使用ajaxSubmit(obj)来提交数据。ajaxSubmit(obj)方法是jQuery的一个插件jquery.form.js里面的方法,所以使用此方法需要先引入这个插件
引入jquery.form.min.js插件
@*表单*@
<script src="~/Plugins/jquery.form.min.js"></script>
用ajaxSubmit(obj)来提交数据
和单表新增类似,打开新增模态框,清空form表单。然后获取页面数据,在做完获取数据、判断、打开加载层之后用ajaxSubmit()进行表单的提交,其他的和单表新增一样,关闭加载层,若新增成功,则关闭模态框,提示成功,最后刷新表格。反之,提示新增失败。(由于layer是Layui插件中的,因此若没有使用Layui插件则将含有layer的提示都改为不含layer的提示)
//弹出新增模态框
function openInsertModel() {
//清空表单
$("#formInsertExaminee").resetForm();
//弹出新增模态框
$("#modInsertExaminee").modal('show');
}
//保存新增
function saveInsertModel() {
//获取页面数据
var studentIDNum = $("#formInsertExaminee [name='StudentIDNum']").val();//身份证号码
var studentNumber = $("#formInsertExaminee [name='StudentNumber']").val();//学号
var uniformAuthenticationCode = $("#formInsertExaminee [name='UniformAuthenticationCode']").val();//认证码
var studentName = $("#formInsertExaminee [name='StudentName']").val();//姓名
var academeId = $("#formInsertExaminee [name='AcademeID']").val();//学院
var specialtyId = $("#formInsertExaminee [name='SpecialtyID']").val();//专业
var gradeId = $("#formInsertExaminee [name='GradeID']").val();//年级
var classId = $("#formInsertExaminee [name='ClassID']").val();//班级
//数据完整性验证
if (academeId > 0 && specialtyId > 0 && gradeId > 0 && classId &&
studentNumber != "" && uniformAuthenticationCode != "" && studentName != "") {
var layIndex = layer.load();//打开加载层
//提交表单
//ajaxSubmit()提交表单:我们直接通过form提交的话,提交后当前页面跳转到form的action所指向的页面。
//然而,很多时候我们并不希望提交表单后页面跳转,那么,我们就可以使用ajaxSubmit(obj)来提交数据
//ajaxSubmit(obj)方法是jQuery的一个插件jquery.form.js里面的方法,所以使用此方法需要先引入这个插件
$("#formInsertExaminee").ajaxSubmit(function (returnJson) {
//关闭加载层
layer.close(layIndex);
//录入成功
if (returnJson.State) {
//关闭模态框
$("#modInsertExaminee").modal("hide");
//提示信息
layer.alert(returnJson.Text, { icon: 1, title: "提示" });
//刷新表格
tabStudent.reload();
} else {
layer.alert(returnJson.Text, { icon: 0, title: "提示" });
}
});
} else {
layer.alert("请填写完整的数据信息!", { icon: 0, title: "提示" });
}
}
控制器
新增的核心语句:
实例化Models的名称.要新增的表格名称.Add(接收要新增数据的变量)
示例:myModels.PW_User.Add(pwUser);
ReturnJsonVo:用来记录状态的State,记录文本Text,还有状态码、附加数据。(详情请见LINQ新增之单表新增)
根据View里面中新增from表单中的from标签中action路径创建方法InsertStudent。用表对象来接收页面传入控制器的数据。根据页面传入的数据判断涉及到的表为用户表、学生表。实例化一个ReturnJsonVo,将其命名为returnJson,用来返回状态和文本。由于涉及到多表,为防止新增中途出现异常而导致数据新增不完整,但却会保存到数据库,因此需要使用事务。开启事务后用try { } catch { }来捕获异常,若出现异常则输出“数据异常”。其实最好在捕获异常前面判断数据是否完整为以防万一,如果不完整,输出”请填写完整”。在捕获异常之后判断传入的数据是否与数据库已有的数据重复。先判断学生信息:根据上面表格可知,学生表中的数据有许多,可以重复的数据也有许多,如:姓名、性别、班级ID等,但是学生的学号(StudentNumber)、身份证号(StudentIDNum)却是惟一的,不能重复。因此,根据学生的学号、身份证号码来判断学生信息是否重复,如果其中一项与数据库重复,则输出"数据重复,该学生信息已经存在,不需要重复录入!"。反之,则继续往下判断用户表中的统一认证码是否重复 。由于用户的账号和密码均为学生的学号,因为在上面判断了学号,账号和密码均不用在判断。输出与前面类似,就不再讲了。判断完之后根据上面注意中分析的新增表格的顺序,首先新增用户表,还是根据上面注意中的账号和密码均为学生的学号,因此将账号和密码赋值为学生的学号(密码最好进行加密,此处已用256位AES进行加密),然后新增用户表(myModels.PW_User.Add(pwUser);)。myModels.SaveChanges()表示保存表格,若myModels.SaveChanges()>0表示保存成功。判断用户表是否新增成功。不成功,输出。成功,继续往下新增学生表,获取新增用户表得到的用户ID,将其赋值给学生表中的用户ID。由于数据库中学生状态均为应届,因此,将学生状态(StudentState)赋值为“应届”。保存表格(myModels.PW_Student.Add(pwStudent);),判断,保存失败则输出。反之,继续往下新增用户角色明细表。实例化用户角色明细表,用来接收用户角色明细表的数据。将上面新增学生表时获取到的用户ID赋值给用户角色明细表的用户ID,根据注意中的第四条,将用户类型ID赋(UserTypeID)值为6。保存表格(myModels.PW_UserRoleDetail.Add(pwUserRoleDetail);)判断,保存失败则输出。反之,将returnJson的状态(State)改为true,返回文本“新增成功”。最后,用Json格式将returnJson返回,并设置允许请求。
public ActionResult InsertStudent(PW_User pwUser, PW_Student pwStudent)
{
ReturnJsonVo returnJson = new ReturnJsonVo();
using (var scope = new TransactionScope())
try
{
//判断学生信息是否重复
int countStudent = (from tbStudent in myModels.PW_Student
where tbStudent.StudentIDNum == pwStudent.StudentIDNum
|| tbStudent.StudentNumber == pwStudent.StudentNumber
select tbStudent).Count();
if (countStudent == 0)
{
//判断认证码是否重复
int countUser = (from tbUser in myModels.PW_User
where tbUser.UniformAuthenticationCode == pwUser.UniformAuthenticationCode
select tbUser).Count();
if (countUser == 0)
{
//账号即学生学号
//新增用户表
pwUser.UserNuber = pwStudent.StudentNumber;
pwUser.Password = AESEncryptHelper.Encrypt(pwStudent.StudentNumber);
myModels.PW_User.Add(pwUser);
if (myModels.SaveChanges() > 0)
{
//获取新增用户的id
var userId = pwUser.UserID;
//开始新增
pwStudent.UserID = userId;
pwStudent.StudentState = "应届";
myModels.PW_Student.Add(pwStudent);
if (myModels.SaveChanges() > 0)
{
//用户角色明细表新增
PW_UserRoleDetail pwUserRoleDetail = new PW_UserRoleDetail();
pwUserRoleDetail.UserID = userId;
pwUserRoleDetail.UserTypeID = 6;
myModels.PW_UserRoleDetail.Add(pwUserRoleDetail);
if (myModels.SaveChanges() > 0)
{
scope.Complete();//提交事务
returnJson.State = true;
returnJson.Text = "考生信息录入成功!";
}
else
{
returnJson.Text = "用户角色明细表录入失败!";
}
}
else
{
returnJson.Text = "学生表保存失败!";
}
}
else
{
returnJson.Text = "用户表保存失败!";
}
}
else
{
returnJson.Text = "该统一认证码已存在!";
}
}
else
{
returnJson.Text = "数据重复,该学生信息已经存在,不需要重复录入!";
}
}
catch (Exception e)
{
returnJson.Text = "数据异常";
Console.WriteLine(e);
}
return Json(returnJson, JsonRequestBehavior.AllowGet);
}