1 Score(成绩)实体重构为Exam(考试)实体

/// <summary>

/// 【考试--类】

/// <remarks>

/// 摘要:

///     通过该实体类及其属性成员,用于实现当前程序【Data】.【领域】.【学生集】.【考试】实体与“[SqlSugarAcquaintance].[Exam]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

/// </remarks>

/// </summary>

public class Exam

{

/// <summary>

/// 【编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置考试实体1个指定实例的整型编号值。

/// [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]标记:

///     该标记将该属性成员所映射[Exam].[Id]字段约束定义主键。

/// </remarks>

[SugarColumn(IsIdentity = true, IsPrimaryKey = true)]

public int Id { get; set; }

/// <summary>

/// 【学生编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置班级实体1个指定实例的整型编号值。

/// 注意:

///     “SqlSugarCore”中间件不支持外键/副键约束映射定义,即在Code-Frist模式下,该属性成员不能像“EFCore”那样被约束定义为:外键/副键

/// </remarks>

public int StudentId { get; set; }

/// <summary>

/// 【课程编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置课程实体1个指定实例的整型编号值。

/// 注意:

///     “SqlSugarCore”中间件不支持外键/副键约束映射定义,即在Code-Frist模式下,该属性成员不能像“EFCore”那样被约束定义为:外键/副键

/// </remarks>

public int CourseId { get; set; }

/// <summary>

/// 【名称】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置一次考试的名称。

///[SugarColumn(ColumnDataType = "nvarchar", Length =255)]标记:

///     该标记将该属性成员所映射[Course].[Name]字段的长度约束定义为:“255”,字段长度约束的默认类型为:“varchar,当前设定类型为;“nvarchar”

/// 同时标记的约束定义权限高于上下文约束定义的权限,即指定表中指定字段长度的约束类型和长度,最终将由该标记约束定义所决定。

/// </remarks>

[SugarColumn(ColumnDataType = "nvarchar", Length = 255)]

public string Name { get; set; }

/// <summary>

/// 【成绩】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定考试实例中的成绩整型值。

/// </remarks>

[SugarColumn(IsNullable = true)]

public int? Score { get; set; }

/// <summary>

/// 【备注】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定考试实例中的备注信息。

/// [SugarColumn(IsNullable = true, ColumnDataType = "nvarchar", Length = int.MaxValue)]标记:

///     该标记将该属性成员所映射[Course].[Comment]字段的长度约束定义为:“int.MaxValue”,字段长度约束的默认类型为:“varchar,当前设定类型为;“nvarchar”

/// 同时标记的约束定义权限高于上下文约束定义的权限,即指定表中指定字段长度的约束类型和长度,最终将由该标记约束定义所决定。

/// </remarks>

[SugarColumn(IsNullable = true, ColumnDataType = "nvarchar", Length = int.MaxValue)]

public string Comment { get; set; }

/// <summary>

/// 【单个学生】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置专业实体的1个指定实例。

/// [Navigate(NavigateType.OneToOne, nameof(StudentId))]

///     该标记在当前程序使用级联查询操作时,直接获取学生实体的1个指定实例,如果该属性没有被该标记所标记则在使用级联查询操作时会出现异常。

/// </remarks>

[SugarColumn(IsIgnore = true)]

[Navigate(NavigateType.OneToOne, nameof(StudentId))]//1:1

public virtual Student StudentSingleton { get; set; }

/// <summary>

/// 【单个课程】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置年级实体的1个指定实例。

/// [Navigate(NavigateType.OneToOne, nameof(CourseId))]

///     该标记在当前程序使用级联查询操作时,直接获取课程实体的1个指定实例,如果该属性没有被该标记所标记则在使用级联查询操作时会出现异常。

/// </remarks>

[SugarColumn(IsIgnore = true)]

[Navigate(NavigateType.OneToOne, nameof(CourseId))]//1:1

public virtual Course CourseSingleton { get; set; }

}

2 DataTable直接分页渲染显示

2.1 DirectRenderController.cs

public class DirectRenderController : Controller

{

private readonly SqlSugarContext _context;

public DirectRenderController(SqlSugarContext context)

{

_context = context;

}

public IActionResult Index()

{

//通过级联操作,获取与考试相关的所有数据,为页面的渲染显示提供支撑。

List<Exam> _examList = _context.SugarScope.Queryable<Exam>()

.Includes(score => score.CourseSingleton)//1层级联

.Includes(

score => score.StudentSingleton,

student => student.SpecialtySingleton)//2层级联

.Includes(

score => score.StudentSingleton,

student => student.CategorySingleton)//2层级联

.Includes(

score => score.StudentSingleton,

student => student.CategorySingleton,

category => category.GradeSingleton)//3层级联

.ToList();

return View(_examList);

}

}

2.2 \DirectRender\Index.cshtml

@using Data.Domain.Students

@model List<Exam>

@{

ViewData["Title"] = "Index";

}

@section styles

{

<link rel="stylesheet" type="text/css" href="~/lib/DataTables-1.12.1/css/dataTables.bootstrap5.css">

}

<div class="row mt-3">

<div class="col-md-12">

<form asp-action="Index">

<div class="card">

<div class="card-body">

<h5 class="card-title"><i class="fas fa-list" aria-hidden="true"></i> 表格</h5>

<table id="example" class="display" style="width:100%">

<thead>

<tr style="width:100%">

<th>编号</th>

<th>学号</th>

<th>姓名</th>

<th>专业</th>

<th>年级</th>

<th>班级</th>

<th>考试名称</th>

<th>课程</th>

<th>成绩</th>

</tr>

</thead>

<tbody>

@foreach (var item in Model)

{

<tr>

<th>@item.Id</th>

<th>@item.StudentSingleton.Code</th>

<th>@item.StudentSingleton.Name</th>

<th>@item.StudentSingleton.SpecialtySingleton.Name</th>

<th>@item.StudentSingleton.CategorySingleton.GradeSingleton.Name</th>

<th>@item.StudentSingleton.CategorySingleton.Name</th>

<th>@item.Name</th>

<th>@item.CourseSingleton.Name</th>

<th>

@if (item.Score == null)

{

@item.Comment

}

else

{

@item.Score

}

</th>

</tr>

}

</tbody>

</table>

</div>

</div>

</form>

</div>

</div>

@section Scripts

{

@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

<script type="text/javascript" src="~/lib/DataTables-1.12.1/js/jquery.dataTables.js"></script>

<script type="text/javascript" src="~/lib/DataTables-1.12.1/js/dataTables.bootstrap5.js"></script>

<script type="text/javascript">

$(document).ready(function () {

$('#example').DataTable({

language: {

url: '../../lib/DataTables-1.12.1/localization/zh.json' //DataTables语言配置选项

},

//样式配置

bLengthChange: true,//是否在DataTableJquery插件中显示下拉框控件,true(默认值):显示。

lengthMenu: [10, 20, 30, 50, 100], //DataTableJquery插件下拉框控件中的数量选择内容。

searching: false, //是否在DataTableJquery插件中显示搜索框控件,false:不显示。

autoWidth: true,//DataTableJquery插件全局自适应宽度,即插件中所有字段的宽度根据浏览器自动调整,true(默认值):自动调整。

bInfo: true,//是否在DataTableJquery插件中显示是否显示信息 就是这个“第 1 至 10 项,共 x 项”信息,true(默认值):显示。

pagingType: "numbers",//该样式类型禁止在DataTableJquery插件中,显示“上页”、“下页”等按钮。

//数据载入配置

//processing: true, //在ajax请求操作获取后端JSON编码格式的数据时,是否显示数据正处于加载...之中信息,true:显示。

//serverSide: true, //开启服务器模式,指示是否把ajax请求操作获取的数据加载到DataTableJquery插件的表格,true:加载。

//排序配置

bSort: true,//是否启用DataTableJquery插件中的表头字段排序按钮,true(默认值):启用。

order: [[0, 'desc']],//设置默认排序字段及其排序方式。

columnDefs:

[

{ targets: [3, 4, 5, 6, 7], orderable: false }//设置DataTableJquery插件中禁止排序的字段。

],

});

});

</script>

}

3 SqlSugarCore中间件内置方法内存逻辑分页,之DataTable渲染显示

3.1 准备工作

3.1.1 SelectListItemExtension.cs(扩展)

/// <summary>

/// 【下拉框控件扩展】

/// </summary>

/// <remarks>

/// 摘要:

///     该类中的方法通过泛型操作,把1个指定类的所有实例,转换后存储到“List<SelectListItem>”实例中,为下拉框控件的渲染显示提供数据支撑。

/// </remarks>

public static class SelectListItemExtension

{

///<typeparam name="T">泛型类型实例(1个指定类的类型实例)。</typeparam>

///<param name="list">列表实例,该实例存储着1个指定类的所有实例。</param>

///<param name="nameProperty">1个指定类中指定属性成员的名称,通过该属性成员的名称,获取该成员的实例,并把该实例赋值给“SelectListItem”的“Text”属性成员。</param>

///<param name="idProperty">1个指定类中指定属性成员的名称,通过该属性成员的名称,获取该成员的实例(该实例一般为指定类1个指定实例的整型编号值),并把该实例赋值给“SelectListItem”的“Value”属性成员。</param>

///<param name="isDefaultItem">指示是否把1个默认的“SelectListItem”实例,存储到“List<SelectListItem/>”实例中,默认值:true,即添加1个默认实例到“List<SelectListItem/>”实例中。</param>

///<param name="defaultItemText">1个默认的“SelectListItem”实例的“Text”属性成员所对应的实例值,默认值:null,即“Text”属性成员无对应的实例值。</param>

///<param name="defaultItemValue">1个默认的“SelectListItem”实例的“Value”属性成员所对应的实例值,默认值:0,即“Value”属性成员所对应的实例值为:0。</param>

/// <summary>

/// 【下拉列表扩展】

/// <remarks>

/// 摘要:

///   该方法通过泛型操作,把1个指定类的所有实例,转换后存储到“List<SelectListItem/>”实例中,为下拉框控件的渲染显示提供数据支撑。

/// </remarks>

/// </summary>

public static List<SelectListItem> AddSelectList<T>(this IList<T> list, string nameProperty, string idProperty,

bool isDefaultItem = true, string defaultItemText = null, string defaultItemValue = "0")

{

if (list == null)

throw new ArgumentNullException(nameof(list));

List<SelectListItem> _selectList = new List<SelectListItem>();

_selectList = list.Select(item => new SelectListItem

{

Text = item.GetType().GetProperty(nameProperty).GetValue(item).ToString(),

Value = item.GetType().GetProperty(idProperty).GetValue(item).ToString(),

}).ToList();

if(isDefaultItem)

{

//1个指定下拉控件项所对应的默认文本值,该参数默认值:null(则默认文本值为:"全部")。

defaultItemText ??= "全部";

//把1个指定下拉控件项实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

_selectList.Insert(0,

new SelectListItem

{

Text = defaultItemText,

Value = defaultItemValue,

});

}

return _selectList;

}

}

3.1.2 BaseSearchModel.cs(抽象纪录)

/// <summary>

/// 【基本查询模型--纪录】

/// </summary>

/// <remarks>

/// 摘要:

///     把Jquery DataTables插件中当前1指定视图页的相关数据信息赋值给该纪录实例,为内存逻辑分页操作提供数据支撑。

/// 说明:

///     该记录被定义为抽象记录,就是为了被不同的指定查询模型记录所继承,如果不继承该抽象基记录,所有指定的查询模型记录,都需要重复性的对该抽象基记录中的所有属性成员进行定义。

/// </remarks>

public abstract record BaseSearchModel

{

#region 属性--Jquery DataTables插件渲染显示基本数据支撑

/// <summary>

/// 【绘制】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置的Jquery DataTable插件在页面中被渲染(显示)出来的次数(当使用Ajax异步请求操作Jquery DataTable插件时,Jquery DataTable插件可能会不按照顺序返回后台action方法,

/// 因此必须通过该属性成员实例,来保证按照前台页面的操作顺序,调用后台action方法从而实现Jquery DataTable插件按照该顺序在页面中被渲染(显示)出来)。

/// 说明;

///     该属性成员实例只用于存储Jquery DataTables插件从前端传递过来的数据,内存逻辑分页操作无需该属性成员实例。

/// </remarks>

public string Draw { get; set; }

#endregion

#region 属性--内存逻辑分页基本数据支撑

/// <summary>

/// 【开始】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置内存逻辑分页操作,需要跳过的项数值:=(页数-1)*Length,Start>=0。

/// </remarks>

public int Start { get; set; } = 0;

/// <summary>

/// 【页面大小】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置内存逻辑分页操作,每1页中存储指定实体实例的最多项数值,默认:10项指定实例,Length>=1。

/// </remarks>

public int Length { get; set; } = 10;

#endregion

#region 属性--排序

/// <summary>

/// 【字段】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置内存逻辑分页操作时的排序字段。

/// </remarks>

public string Column { get; set; }

/// <summary>

/// 【方式】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置内存逻辑分页操作时的排序方式:“asc/desc”。

/// </remarks>

public string Dir { get; set; }

#endregion

}

3.1.3 ExamSearchModel.cs(查询表单渲染,和为表格渲染提供支撑)

/// <summary>

/// 【考试查询模型--纪录】

/// </summary>

/// <remarks>

/// 摘要:

///     把当前1指定视图页中Jquery DataTables插件和表单中的相关数据信息赋值给该纪录及其基纪录实例,为内存逻辑分页操作提供数据支撑。

/// </remarks>

public record ExamSearchModel : BaseSearchModel

{

#region 拷贝构造方法

/// <summary>

/// 【拷贝构造方法】

/// </summary

/// <remarks>

/// 摘要:

///     实例化该纪录时,为列表接口类型的属性成员实例分配内存空间。

/// </remarks>

public ExamSearchModel()

{

SpecialtySelectList = new List<SelectListItem>();

GradeSelectList = new List<SelectListItem>();

CategorySelectList = new List<SelectListItem>();

}

#endregion

#region 属性--查询

/// <summary>

/// 【学号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置学生实体1个指定实例的学号。

/// </remarks>

[Display(Name = "学号")]

public string Code { get; set; }

/// <summary>

/// 【姓名】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定学生的姓名。

/// </remarks>

[Display(Name = "姓名")]

public string Name { get; set; }

/// <summary>

/// 【专业编号】

/// <remarks>

/// </summary>

/// 摘要:

///     获取/设置专业实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "专业")]

public int SpecialtyId { get; set; }

/// <summary>

/// 【年级编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置年级实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "年级")]

public int GradeId { get; set; }

/// <summary>

/// 【班级编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置班级实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "班级")]

public int CategoryId { get; set; }

/// <summary>

/// 【专业选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把专业实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> SpecialtySelectList { get; set; }

/// <summary>

/// 【年级选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把年级实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> GradeSelectList { get; set; }

/// <summary>

/// 【班级选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把班级实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> CategorySelectList { get; set; }

#endregion

}

3.1.4 ExamModel.cs(表格渲染、添加和修改渲染显示)

/// <summary>

/// 【考试模型--纪录】

/// </summary>

/// <remarks>

/// 摘要:

///     把内存逻辑分页实例中的每1项实例,依次转换存储到该模型纪录的1个指定实例中,为Jquery DataTables插件表中每1行的渲染显示提供数据支撑。

/// </remarks>

public record ExamModel

{

#region 拷贝构造方法

/// <summary>

/// 【拷贝构造方法】

/// </summary

/// <remarks>

/// 摘要:

///     实例化该纪录时,为列表接口类型的属性成员实例分配内存空间。

/// </remarks>

public ExamModel()

{

SpecialtySelectList = new List<SelectListItem>();

GradeSelectList = new List<SelectListItem>();

CategorySelectList = new List<SelectListItem>();

}

#endregion

#region 属性--表格

/// <summary>

/// 【编号】

/// <remarks>

/// 摘要:

///     获取/设置学生实体1个指定实例的整型编号值。

/// </remarks>

/// </summary>

public int Id { get; set; }

/// <summary>

/// 【学号】

/// <remarks>

/// 摘要:

///     获取/设置学生实体1个指定实例的学号。

/// </remarks>

/// </summary>

[Display(Name = "学号")]

public string Code { get; set; }

/// <summary>

/// 【姓名】

/// <remarks>

/// 摘要:

///     获取/设置1个指定学生的姓名。

/// </remarks>

/// </summary>

[Display(Name = "姓名")]

public string StudentName { get; set; }

/// <summary>

/// 【专业名称】

/// <remarks>

/// 摘要:

///     获取/设置专业实体1个指定实例的名称。

/// </remarks>

/// </summary>

public string SpecialtyName { get; set; }

/// <summary>

/// 【年级名称】

/// <remarks>

/// 摘要:

///     获取/设置年级实体1个指定实例的名称。

/// </remarks>

/// </summary>

public string GradeName { get; set; }

/// <summary>

/// 【班级名称】

/// <remarks>

/// 摘要:

///     获取/设置班级实体1个指定实例的名称。

/// </remarks>

/// </summary>

public string CategoryName { get; set; }

/// <summary>

/// 【课程名称】

/// <remarks>

/// 摘要:

///     获取/设置课程实体1个指定实例的名称。

/// </remarks>

/// </summary>

public string CourseName { get; set; }

/// <summary>

/// 【名称】

/// <remarks>

/// 摘要:

///     获取/设置1个指定考试的名称。

/// </remarks>

/// </summary>

[Display(Name = "考试名称")]

public string Name { get; set; }

/// <summary>

/// 【成绩】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定成绩实例中的成绩整型值。

/// </remarks>

[Display(Name = "成绩")]

public int? Score { get; set; }

/// <summary>

/// 【备注】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定成绩实例中的备注信息。

/// </remarks>

[Display(Name = "备注")]

public string Comment { get; set; }

#endregion

#region 属性--添加/编辑

/// <summary>

/// 【专业编号】

/// <remarks>

/// </summary>

/// 摘要:

///     获取/设置专业实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "专业")]

public int SpecialtyId { get; set; }

/// <summary>

/// 【年级编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置年级实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "年级")]

public int GradeId { get; set; }

/// <summary>

/// 【班级编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置班级实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "班级")]

public int CategoryId { get; set; }

/// <summary>

/// 【班级编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置班级实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "课程")]

public int CourseId { get; set; }

/// <summary>

/// 【学生编号】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置班级实体1个指定实例的整型编号值。

/// </remarks>

[Display(Name = "姓名")]

public int StudentId { get; set; }

/// <summary>

/// 【专业选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把专业实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> SpecialtySelectList { get; set; }

/// <summary>

/// 【年级选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把年级实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> GradeSelectList { get; set; }

/// <summary>

/// 【班级选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把班级实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> CategorySelectList { get; set; }

/// <summary>

/// 【课程选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把课程实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> CourseSelectList { get; set; }

/// <summary>

/// 【学生选择列表实例】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置把学生实体的所有下拉列表实例,存储到列表接口实例中。

/// </remarks>

public IList<SelectListItem> StudentSelectList { get; set; }

#endregion

}

3.1.5 PagedListModel(DataTables渲染)

///<typeparam name="T">泛型类型实例(1个指定模型纪录的类型实例)。</typeparam>

/// <summary>

/// 【渲染显示分页模型--纪录】

/// </summary>

/// <remarks>

/// 摘要:

///     把内存逻辑分页实例中的每1项实例,依次转换存储到指定模型纪录的1个指定实例中后,把这些转换后的模型纪录所有的实例,

/// 存储到该纪录实例的枚举数接口实例中,为Jquery DataTables插件表中每1行的渲染显示提供数据支撑。

/// 说明:

///     模型纪录类型实例的指定,是通过泛型“<T>”的实现的。

/// </remarks>

public record PagedListModel<T>

{

#region 属性--Jquery DataTables插件渲染显示基本数据支撑

/// <summary>

/// 【数据】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个枚举数接口实例,该实例存储着1个指定泛型“<T>”类中的所有的实例,为Jquery DataTable插件中的表格渲染显示提供数据支撑。

/// 注意:

///     因为Jquery DataTable插件是通过Jquery Ajax操作在浏览器中渲染出1指定类中的所有实例数据,所以该属性必须被命名为“Data”,也只能被命名为“Data”,否则浏览器中将不会渲染出这些数据。

/// </remarks>

public IEnumerable<T> Data { get; set; }

/// <summary>

/// 【绘制】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定的Jquery DataTable插件被操作的次数值。

/// [JsonProperty(PropertyName = "string")]标记:

///      如果对继承于该纪录的具体纪录实例在使用调用 Json(object)方法时,都会转到JsonConvert.SerializeObject(object)方法对具体纪录实例进行序列化编码,编码后的JSON数据中键(key)名,

/// 是通过[JsonProperty(PropertyName = "string")]标记所指定的键(key)名;在C#中如果不使用[JsonProperty(PropertyName = "string")]标记,则JSON数据中键(key)名与与属性成员名相同。

/// 但是在Jquery中JSON数据中键(key)名的第1个字母必须是小写字母,否则,将不会获取该键(key)名及其相对应值,为了让JSON数据同时兼容C#和Jquery,

/// 所以通过[JsonProperty(PropertyName = "string")]标记,把当前属性成员的第1个字母特定指定为小写字母,让Jquery能够获取JSON数据中键(key)名及其相对应值。

/// </remarks>

[JsonProperty(PropertyName = "draw")]

public string Draw { get; set; }

/// <summary>

/// 【过滤总计】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置符合指定过滤条件的1个指定实体所有实例的总计值。

/// [JsonProperty(PropertyName = "string")]:

///      如果对继承于该纪录的具体纪录实例在使用调用 Json(object)方法时,都会转到JsonConvert.SerializeObject(object)方法对具体纪录实例进行序列化编码,编码后的JSON数据中键(key)名,

/// 是通过[JsonProperty(PropertyName = "string")]标记所指定的键(key)名;在C#中如果不使用[JsonProperty(PropertyName = "string")]标记,则JSON数据中键(key)名与与属性成员名相同。

/// 但是在Jquery中JSON数据中键(key)名的第1个字母必须是小写字母,否则,将不会获取该键(key)名及其相对应值,为了让JSON数据同时兼容C#和Jquery,

/// 所以通过[JsonProperty(PropertyName = "string")]标记,把当前属性成员的第1个字母特定指定为小写字母,让Jquery能够获取JSON数据中键(key)名及其相对应值。

/// </remarks>

[JsonProperty(PropertyName = "recordsFiltered")]

public int RecordsFiltered { get; set; }

/// <summary>

/// 【总计】

/// </summary>

/// <remarks>

/// 摘要:

///     获取/设置1个指定实体所有实例的总计值。

/// [JsonProperty(PropertyName = "string")]:

///      如果对继承于该纪录的具体纪录实例在使用调用 Json(object)方法时,都会转到JsonConvert.SerializeObject(object)方法对具体纪录实例进行序列化编码,编码后的JSON数据中键(key)名,

/// 是通过[JsonProperty(PropertyName = "string")]标记所指定的键(key)名;在C#中如果不使用[JsonProperty(PropertyName = "string")]标记,则JSON数据中键(key)名与与属性成员名相同。

/// 但是在Jquery中JSON数据中键(key)名的第1个字母必须是小写字母,否则,将不会获取该键(key)名及其相对应值,为了让JSON数据同时兼容C#和Jquery,

/// 所以通过[JsonProperty(PropertyName = "string")]标记,把当前属性成员的第1个字母特定指定为小写字母,让Jquery能够获取JSON数据中键(key)名及其相对应值。

/// </remarks>

[JsonProperty(PropertyName = "recordsTotal")]

public int RecordsTotal { get; set; }

#endregion

#region 属性--Jquery DataTables插件渲染显示分页数据支撑

/// <summary>

/// 【开始】

/// <remarks>

/// 摘要:

///     获取/设置1个指定的Jquery DataTable插件当前显示页面,Start>=0。

/// </remarks>

/// </summary>

public int Start { get; set; }

/// <summary>

/// 【长度】

/// <remarks>

/// 摘要:

///     获取/设置1个指定的Jquery DataTable插件每页最多的行数值:(默认值)10,Length>=1。

/// </remarks>

/// </summary>

public int Length { get; set; }

#endregion

}

3.2 分页、增、修、删

3.2.1 LogicRenderController.cs

using Data;

using Data.Domain.Students;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.Rendering;

using SqlSugar;

using Web.Extensions;

using Web.Models;

namespace Web.Controllers

{

public class LogicRenderController : Controller

{

private readonly SqlSugarContext _context;

public LogicRenderController(SqlSugarContext context)

{

_context = context;

}

#region 方法--私有/保护

/// <param name="studentSearchModel">1个指定的学生查询模型实例。</param>

/// <summary>

/// 【预处理成绩表单】

/// <remarks>

/// 摘要:

///     通过参数实例,初始化设置页面中的查询表单和Jquery DataTable插件。

/// </remarks>

/// </summary>

protected virtual ExamSearchModel PrepareScoreSearchModel(ExamSearchModel model)

{

model.SpecialtySelectList = PrepareSpecialty();

model.GradeSelectList = PrepareGrade();

model.CategorySelectList = new List<SelectListItem>();

return model;

}

protected IList<SelectListItem> PrepareSpecialty(int id=0, bool isDefaultItem = true)

{

List<Specialty> _specialtyList = _context.SugarScope.Queryable<Specialty>().ToList();

return _specialtyList.AddSelectList(nameof(Specialty.Name), nameof(Specialty.Id), isDefaultItem);

}

protected IList<SelectListItem> PrepareGrade(int id=0, bool isDefaultItem = true)

{

List<Grade> _gradeList = _context.SugarScope.Queryable<Grade>().ToList();

return _gradeList.AddSelectList(nameof(Grade.Name), nameof(Grade.Id), isDefaultItem);

}

protected IList<SelectListItem> PrepareCategory(int id = 0, bool isDefaultItem = true)

{

List<Category> _categoryList = _context.SugarScope.Queryable<Category>().ToList();

return _categoryList.AddSelectList(nameof(Category.Name), nameof(Category.Id), isDefaultItem);

}

protected IList<SelectListItem> PrepareStudent(int id = 0, bool isDefaultItem = true)

{

List<Student> _studentList = _context.SugarScope.Queryable<Student>().ToList();

return _studentList.AddSelectList(nameof(Student.Name), nameof(Student.Id), isDefaultItem);

}

protected IList<SelectListItem> PrepareCourse(int id = 0, bool isDefaultItem = true)

{

List<Course> _courseList = _context.SugarScope.Queryable<Course>().ToList();

return _courseList.AddSelectList(nameof(Course.Name), nameof(Course.Id), isDefaultItem);

}

#endregion

public IActionResult Index()

{

ExamSearchModel _model = PrepareScoreSearchModel(new ExamSearchModel());

return View(_model);

}

public IActionResult CreatePopup()

{

ExamModel _examModel = new ExamModel();

_examModel.SpecialtySelectList = PrepareSpecialty(0, true);

_examModel.GradeSelectList = PrepareGrade(0, true);

_examModel.CourseSelectList = PrepareCourse(0, true);

_examModel.CategorySelectList = new List<SelectListItem>();

_examModel.StudentSelectList = new List<SelectListItem>();

ViewBag.RefreshPage = false;

return View(_examModel);

}

[HttpPost]

public async Task<IActionResult> CreatePopup(ExamModel model)

{

Exam _exam = new Exam();

_exam.Score = model.Score;

_exam.Comment= model.Comment;

_exam.Name = model.Name;

_exam.CourseId = model.CourseId;

_exam.StudentId = model.StudentId;

await _context.SugarScope.Insertable(_exam).ExecuteReturnEntityAsync();

model.SpecialtySelectList = PrepareSpecialty(0, true);

model.GradeSelectList = PrepareGrade(0, true);

model.CourseSelectList = PrepareCourse(0, true);

model.CategorySelectList = new List<SelectListItem>();

model.StudentSelectList = new List<SelectListItem>();

ViewBag.RefreshPage = true;

return View(model);

}

public async Task<IActionResult> EditPopup(int id)

{

Exam _model = await _context.SugarScope.Queryable<Exam>()

.Includes(score => score.CourseSingleton)//1层级联

.Includes(

exam => exam.StudentSingleton,

student => student.SpecialtySingleton)//2层级联

.Includes(

exam => exam.StudentSingleton,

student => student.CategorySingleton)//2层级联

.Includes(

exam => exam.StudentSingleton,

student => student.CategorySingleton,

category => category.GradeSingleton)//3层级联

.InSingleAsync(id);

ExamModel _examModel = new ExamModel();

_examModel.Id = id;

_examModel.Code = _model.StudentSingleton.Code;

_examModel.StudentName = _model.StudentSingleton.Name;

_examModel.Name = _model.Name;

_examModel.Score = _model.Score;

_examModel.Comment = _model.Comment;

_examModel.SpecialtyId = _model.StudentSingleton.SpecialtyId;

_examModel.GradeId = _model.StudentSingleton.CategorySingleton.GradeId;

_examModel.CourseId = _model.CourseId;

_examModel.CategoryId = _model.StudentSingleton.CategoryId;

_examModel.StudentId = _model.StudentId;

_examModel.SpecialtySelectList = PrepareSpecialty(_examModel.SpecialtyId, false);

_examModel.GradeSelectList = PrepareGrade(_examModel.GradeId, false);

_examModel.CourseSelectList = PrepareCourse(_examModel.CourseId, false);

_examModel.CategorySelectList = PrepareCategory(_examModel.CategoryId, false);

_examModel.StudentSelectList = PrepareStudent(_examModel.StudentId, false);

ViewBag.RefreshPage = false;

return View(_examModel);

}

[HttpPost]

public async Task<IActionResult> EditPopup(ExamModel model)

{

Exam _model = new Exam();

_model.Id = model.Id;

_model.Name = model.Name;

_model.Comment = model.Comment;

_model.CourseId = model.CourseId;

_model.StudentId = model.StudentId;

_model.Score = model.Score;

await _context.SugarScope.Updateable(_model).ExecuteCommandAsync();

_model = await _context.SugarScope.Queryable<Exam>()

.Includes(score => score.CourseSingleton)//1层级联

.Includes(

exam => exam.StudentSingleton,

student => student.SpecialtySingleton)//2层级联

.Includes(

exam => exam.StudentSingleton,

student => student.CategorySingleton)//2层级联

.Includes(

exam => exam.StudentSingleton,

student => student.CategorySingleton,

category => category.GradeSingleton)//3层级联

.InSingleAsync(model.Id);

model.SpecialtyId = _model.StudentSingleton.SpecialtyId;

model.GradeId = _model.StudentSingleton.CategorySingleton.GradeId;

model.CourseId = _model.CourseId;

model.CategoryId = _model.StudentSingleton.CategoryId;

model.StudentId = _model.StudentId;

model.SpecialtySelectList = PrepareSpecialty(model.SpecialtyId, false);

model.GradeSelectList = PrepareGrade(model.GradeId, false);

model.CourseSelectList = PrepareCourse(model.CourseId, false);

model.CategorySelectList = PrepareCategory(model.CategoryId, false);

model.StudentSelectList = PrepareStudent(model.StudentId, false);

ViewBag.RefreshPage = true;

return View(model);

}

#region 方法--Ajax

/// <param name="gradeId">年级实体1个指定实例的整型编号值,默认值:0,即班级下拉框控件没有任何项。</param>

/// <summary>

/// 【班级下拉控件局部刷新】

/// </summary>

/// <remarks>

/// 摘要:

///     通过参数实例,实现年级下拉框控件联动局部刷新班级下拉框控件。

/// </remarks>

/// <returns>

///     班级下拉控件局部刷新渲染所需要的JSON编码格式的数据。

/// </returns>

[HttpPost]

public async Task<IActionResult> CategorySelectListAjax(int? gradeId = 0)

{

List<SelectListItem> _selectList = new List<SelectListItem>();

if (gradeId != 0)

{

List<Category> _categoryList = await _context.SugarScope.Queryable<Category>()

.Where(categary => categary.GradeId == gradeId)

.ToListAsync();

_selectList = _categoryList.AddSelectList(nameof(Category.Name), nameof(Category.Id));

}

return Json(_selectList);

}

/// <param name="categaryId">学生实体1个指定实例的整型编号值,默认值:0,即学生下拉框控件没有任何项。</param>

/// <summary>

/// 【学生下拉控件局部刷新】

/// </summary>

/// <remarks>

/// 摘要:

///     通过参数实例,实现班级下拉框控件联动局部刷新学生下拉框控件。

/// </remarks>

/// <returns>

///     班级下拉控件局部刷新渲染所需要的JSON编码格式的数据。

/// </returns>

[HttpPost]

public async Task<IActionResult> StudentSelectListAjax(int? categaryId = 0)

{

List<SelectListItem> _selectList = new List<SelectListItem>();

if (categaryId != 0)

{

List<Student> _studentList = await _context.SugarScope.Queryable<Student>()

.Where(student => student.CategoryId == categaryId).ToListAsync();

_selectList = _studentList.AddSelectList(nameof(Student.Name), nameof(Student.Id));

}

return Json(_selectList);

}

/// <param name="studentId">学生实体1个指定实例的整型编号值,默认值:0,即学生编号控件内没有任何值。</param>

/// <summary>

/// 【学生编号控件局部刷新】

/// </summary>

/// <remarks>

/// 摘要:

///     通过参数实例,实现学生下拉框控件联动局部刷学生编号控件。

/// </remarks>

/// <returns>

///     学生编号控件局部刷新渲染所需要的JSON编码格式的数据。

/// </returns>

[HttpPost]

public async Task<IActionResult> CodeSelectListAjax(int? studentId = 0)

{

Student _model = new Student();

if (studentId != 0)

{

_model = await _context.SugarScope.Queryable<Student>().InSingleAsync(studentId);

}

return Json(_model.Code);

}

/// <param name="gradeId">年级实体1个指定实例的整型编号值,默认值:0,即班级下拉框控件没有任何项。</param>

/// <summary>

/// 【班级下拉控件局部刷新】

/// </summary>

/// <remarks>

/// 摘要:

///     通过参数实例,实现年级下拉框控件联动局部刷新班级下拉框控件。

/// </remarks>

/// <returns>

///     班级下拉控件局部刷新渲染所需要的JSON编码格式的数据。

/// </returns>

//public IActionResult StudentSelectListAjax(int? gradeId = 0)

//{

//    List<SelectListItem> _selectList = new List<SelectListItem>();

//    if (gradeId != 0)

//    {

//        List<Student> _studentList = _context.SugarScope.Queryable<Student>().ToList();

//        _studentList = _studentList.Where(categary => categary.GradeId == gradeId).ToList();

//        _selectList = _categoryList.AddSelectList(nameof(Student.Name), nameof(Student.Id));

//    }

//    return Json(_selectList);

//}

/// <summary>

/// 【成绩表格局部刷新】

/// </summary>

/// <remarks>

/// 摘要:

///     通过参数实例,实现成绩表格“DataTables”插件的局部刷新渲染显示。

/// </remarks>

/// <returns>

///    成绩表格“DataTables”插件的局部刷新渲染显示,提供JSON编码格式的数据支撑。

/// </returns>

[HttpPost]

public async Task<IActionResult> ScoreListAjax(ExamSearchModel model)

{

//获取DataTable插件当前所设定的排序方式。

OrderByType _orderByType = model.Dir.Equals("asc") ? OrderByType.Asc : OrderByType.Desc;

//指定当前DataTable插件,将由那个表头字段进行排序操作。

bool _isIdOrder = model.Column.ToLower().Equals(nameof(ExamModel.Id).ToLower());

bool _isStudentOrder = model.Column.ToLower().Equals(nameof(ExamModel.StudentName).ToLower());

bool _isCodeOrder = model.Column.ToLower().Equals(nameof(ExamModel.Code).ToLower());

bool _isScoreOrder = model.Column.ToLower().Equals(nameof(ExamModel.Score).ToLower());

//获取考试表排序后的所有实例。

ISugarQueryable<Exam> _scoreQueryable = _context.SugarScope.Queryable<Exam>()

.Includes(score => score.CourseSingleton)//1层级联

.Includes(

exam => exam.StudentSingleton,

student => student.SpecialtySingleton)//2层级联

.Includes(

exam => exam.StudentSingleton,

student => student.CategorySingleton)//2层级联

.Includes(

exam => exam.StudentSingleton,

student => student.CategorySingleton,

category => category.GradeSingleton)//3层级联

.OrderByIF(_isIdOrder, itme => itme.Id, _orderByType)

.OrderByIF(_isStudentOrder, itme => itme.StudentSingleton.Name, _orderByType)

.OrderByIF(_isCodeOrder, itme => itme.StudentSingleton.Code, _orderByType)

.OrderByIF(_isScoreOrder, itme => itme.Score, _orderByType);

//获取符合指定查询条件考试表中的所有实例。

_scoreQueryable = _scoreQueryable

.WhereIF(!string.IsNullOrEmpty(model.Code), itme => itme.StudentSingleton.Code == model.Code)

.WhereIF(!string.IsNullOrEmpty(model.Name), itme => itme.StudentSingleton.Name.Contains(model.Name))

.WhereIF(model.SpecialtyId >= 1, itme => itme.StudentSingleton.SpecialtyId == model.SpecialtyId)

.WhereIF(model.CategoryId >= 1, itme => itme.StudentSingleton.CategoryId == model.CategoryId)

.WhereIF(model.GradeId >= 1, itme => itme.StudentSingleton.CategorySingleton.GradeSingleton.Id== model.GradeId);

RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解。

total = await _scoreQueryable.CountAsync();//获取符合指定查询条件考试表中的所有实例的总计值。

//通过“SqlSugarCore”中间件的内置方法,对内存中所存储的所有考试实例,进行逻辑分页操作,并把该指定逻辑1页内的所有数据,存储到列表实例中。

List<Exam> _examList = await _scoreQueryable

.ToPageListAsync(model.Start / model.Length, model.Length, total);

//把指定逻辑1页内的所有数据,依次转换后存储到相应的模型实例中,并把这些模型实例,存储到列表实例中,该列表实例将为DataTable插件中表格的渲染显示提供支撑。

List<ExamModel> _examModelList = _examList.Select(item => new ExamModel()

{

Id = item.Id,

Code = item.StudentSingleton.Code,

StudentName = item.StudentSingleton.Name,

SpecialtyName = item.StudentSingleton.SpecialtySingleton.Name,

GradeName = item.StudentSingleton.CategorySingleton.GradeSingleton.Name,

CategoryName = item.StudentSingleton.CategorySingleton.Name,

CourseName = item.CourseSingleton.Name,

Name = item.Name,

Score = item.Score,

Comment = item.Comment,

}).ToList();

//实例化分页列表模型实例,该实例将为DataTable插件整体性的渲染显示提供支撑。

PagedListModel<ExamModel> _pagedListModel = new PagedListModel<ExamModel>();

_pagedListModel.Draw = model.Draw;

_pagedListModel.Start = model.Start;

_pagedListModel.Length = model.Length;

_pagedListModel.RecordsTotal = total;

_pagedListModel.RecordsFiltered = total;

_pagedListModel.Data = _examModelList;

return Json(_pagedListModel);

}

[HttpPost]

public async Task<IActionResult> DelelteExamArrayAjax(int[] IdArray)

{

try

{

int result = 0;

result = await _context.SugarScope.Deleteable<Exam>().In(IdArray).ExecuteCommandAsync();

if (result > 0)

{

return Json(new { isDeleted = true });

}

else

{

return Json(new { isDeleted = false });

}

}

catch (Exception)

{

throw;

}

}

#endregion

}

}

3.2.2 LogicRender\Index.cshtml

@model Web.Models.ExamModel

@{

Layout = "_PopupLayout";

ViewData["Title"] = "成绩编辑";

}

<div class="row mt-4 me-3">

<div class="col-md-12">

<form asp-action="CreatePopup"

asp-route-btnId="@Context.Request.Query["btnId"]">

<div class="row mb-3">

<label asp-for="SpecialtyId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="SpecialtyId" class="form-select" asp-items="Model.SpecialtySelectList"></select>

</div>

</div>

<div class="row mb-3">

<label asp-for="CourseId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="CourseId" class="form-select" asp-items="Model.CourseSelectList"></select>

</div>

</div>

<div class="row mb-3">

<label asp-for="GradeId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="GradeId" class="form-select" asp-items="Model.GradeSelectList"></select>

</div>

</div>

<div class="row mb-3 d-none" id="categoryRow">

<label asp-for="CategoryId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="CategoryId" class="form-select" asp-items="Model.CategorySelectList"></select>

</div>

</div>

<div class="row mb-3 d-none" id="studentRow">

<label asp-for="StudentId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="StudentId" class="form-select" asp-items="Model.StudentSelectList"></select>

</div>

</div>

<div class="row mb-3 d-none" id="codeRow">

<label asp-for="Code" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Code" readonly class="form-control-plaintext" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Name" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Name" class="form-control" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Score" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Score" class="form-control" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Comment" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<textarea asp-for="Comment" class="form-control" style="height:100px"></textarea>

</div>

</div>

<div class="form-group text-center">

<input type="submit" value="提 交" class="btn btn-primary mt-3" />

</div>

</form>

</div>

</div>

@section Scripts

{

@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}

<script type="text/javascript">

//年级下拉框控件联动局部刷新班级下拉框控件。

$('#GradeId').on('change', function () {

var gradeId = $(this).val();

$.ajax({

url: "/LogicRender/CategorySelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"gradeId": gradeId,

},

success: function (data) {

if (gradeId == 0) {

$("#categoryRow").addClass('d-none'); // 隐藏

}

else {

$("#categoryRow").removeClass('d-none'); //显示

}

$('#CategoryId').empty();

$.each(data,

function (id, option) {

$('#CategoryId').append($('<option></option>').val(option.value).html(option.text));

});

}

});

});

//班级下拉框控件联动局部刷新学生下拉框控件。

$('#CategoryId').on('change', function () {

var categaryId = $(this).val();

$.ajax({

url: "/LogicRender/StudentSelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"categaryId": categaryId,

},

success: function (data) {

if (categaryId == 0) {

$("#studentRow").addClass('d-none'); // 隐藏

}

else {

$("#studentRow").removeClass('d-none'); //显示

}

$('#StudentId').empty();

$.each(data,

function (id, option) {

$('#StudentId').append($('<option></option>').val(option.value).html(option.text));

});

}

});

});

//学生下拉框控件联动局部刷新学生编号控件。

$('#StudentId').on('change', function () {

var studentId = $(this).val();

$.ajax({

url: "/LogicRender/CodeSelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"studentId": studentId,

},

success: function (data) {

if (studentId == 0) {

$("#codeRow").addClass('d-none'); // 隐藏

}

else {

$("#codeRow").removeClass('d-none'); //显示

}

$('#Code').val(data);

}

});

});

//在数据持久化到指定表后,自动通过父窗口中指定按钮标签的单击事件,自动关闭当前弹出窗口。

if ("@ViewBag.RefreshPage" == "True") {

//获取父窗口中指定按钮标签。

//window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

window.opener.$("#@Context.Request.Query["btnId"]").click();

window.close();

}

</script>

}

3.2.3 LogicRender\CreatePopup.cshtml

@model Web.Models.ExamModel

@{

Layout = "_PopupLayout";

ViewData["Title"] = "成绩编辑";

}

<div class="row mt-4 me-3">

<div class="col-md-12">

<form asp-action="CreatePopup"

asp-route-btnId="@Context.Request.Query["btnId"]">

<div class="row mb-3">

<label asp-for="SpecialtyId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="SpecialtyId" class="form-select" asp-items="Model.SpecialtySelectList"></select>

</div>

</div>

<div class="row mb-3">

<label asp-for="CourseId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="CourseId" class="form-select" asp-items="Model.CourseSelectList"></select>

</div>

</div>

<div class="row mb-3">

<label asp-for="GradeId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="GradeId" class="form-select" asp-items="Model.GradeSelectList"></select>

</div>

</div>

<div class="row mb-3 d-none" id="categoryRow">

<label asp-for="CategoryId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="CategoryId" class="form-select" asp-items="Model.CategorySelectList"></select>

</div>

</div>

<div class="row mb-3 d-none" id="studentRow">

<label asp-for="StudentId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="StudentId" class="form-select" asp-items="Model.StudentSelectList"></select>

</div>

</div>

<div class="row mb-3 d-none" id="codeRow">

<label asp-for="Code" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Code" readonly class="form-control-plaintext" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Name" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Name" class="form-control" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Score" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Score" class="form-control" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Comment" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<textarea asp-for="Comment" class="form-control" style="height:100px"></textarea>

</div>

</div>

<div class="form-group text-center">

<input type="submit" value="提 交" class="btn btn-primary mt-3" />

</div>

</form>

</div>

</div>

@section Scripts

{

@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}

<script type="text/javascript">

//年级下拉框控件联动局部刷新班级下拉框控件。

$('#GradeId').on('change', function () {

var gradeId = $(this).val();

$.ajax({

url: "/LogicRender/CategorySelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"gradeId": gradeId,

},

success: function (data) {

if (gradeId == 0) {

$("#categoryRow").addClass('d-none'); // 隐藏

}

else {

$("#categoryRow").removeClass('d-none'); //显示

}

$('#CategoryId').empty();

$.each(data,

function (id, option) {

$('#CategoryId').append($('<option></option>').val(option.value).html(option.text));

});

}

});

});

//班级下拉框控件联动局部刷新学生下拉框控件。

$('#CategoryId').on('change', function () {

var categaryId = $(this).val();

$.ajax({

url: "/LogicRender/StudentSelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"categaryId": categaryId,

},

success: function (data) {

if (categaryId == 0) {

$("#studentRow").addClass('d-none'); // 隐藏

}

else {

$("#studentRow").removeClass('d-none'); //显示

}

$('#StudentId').empty();

$.each(data,

function (id, option) {

$('#StudentId').append($('<option></option>').val(option.value).html(option.text));

});

}

});

});

//学生下拉框控件联动局部刷新学生编号控件。

$('#StudentId').on('change', function () {

var studentId = $(this).val();

$.ajax({

url: "/LogicRender/CodeSelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"studentId": studentId,

},

success: function (data) {

if (studentId == 0) {

$("#codeRow").addClass('d-none'); // 隐藏

}

else {

$("#codeRow").removeClass('d-none'); //显示

}

$('#Code').val(data);

}

});

});

//在数据持久化到指定表后,自动通过父窗口中指定按钮标签的单击事件,自动关闭当前弹出窗口。

if ("@ViewBag.RefreshPage" == "True") {

//获取父窗口中指定按钮标签。

//window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

window.opener.$("#@Context.Request.Query["btnId"]").click();

window.close();

}

</script>

}

3.2.4 LogicRender\EditPopup.cshtml

@model Web.Models.ExamModel

@{

Layout = "_PopupLayout";

ViewData["Title"] = "成绩编辑";

}

<div class="row mt-4 me-3">

<div class="col-md-12">

<form asp-action="EditPopup"

asp-route-Id="@Context.Request.Query["Id"]"

asp-route-btnId="@Context.Request.Query["btnId"]">

<div class="row mb-3">

<label asp-for="SpecialtyId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="SpecialtyId" class="form-select" asp-items="@(new SelectList(Model.SpecialtySelectList,"Value","Text", Model.SpecialtyId))"></select>

</div>

</div>

<div class="row mb-3">

<label asp-for="CourseId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="CourseId" class="form-select" asp-items="@(new SelectList(Model.CourseSelectList,"Value","Text", Model.CourseId))"></select>

</div>

</div>

<div class="row mb-3">

<label asp-for="GradeId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="GradeId" class="form-select" asp-items="@(new SelectList(Model.GradeSelectList,"Value","Text", Model.GradeId))"></select>

</div>

</div>

<div class="row mb-3" id="categoryRow">

<label asp-for="CategoryId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="CategoryId" class="form-select" asp-items="@(new SelectList(Model.CategorySelectList,"Value","Text", Model.CategoryId))"></select>

</div>

</div>

<div class="row mb-3" id="studentRow">

<label asp-for="StudentId" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<select asp-for="StudentId" class="form-select" asp-items="@(new SelectList(Model.StudentSelectList,"Value","Text", Model.SpecialtyId))"></select>

</div>

</div>

<div class="row mb-3" id="codeRow">

<label asp-for="Code" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Code" readonly class="form-control-plaintext" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Name" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Name" class="form-control" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Score" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<input asp-for="Score" class="form-control" />

</div>

</div>

<div class="row mb-3">

<label asp-for="Comment" class="col-sm-2 col-form-label text-end"></label>

<div class="col-sm-10">

<textarea asp-for="Comment" class="form-control" style="height:100px"></textarea>

</div>

</div>

<div class="form-group text-center">

<input type="submit" value="提 交" class="btn btn-primary mt-3" />

</div>

</form>

</div>

</div>

@section Scripts {

@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

<script type="text/javascript">

//年级下拉框控件联动局部刷新班级下拉框控件。

$('#GradeId').on('change', function () {

var gradeId = $(this).val();

$.ajax({

url: "/LogicRender/CategorySelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"gradeId": gradeId,

},

success: function (data) {

if (gradeId == 0) {

$("#categoryRow").addClass('d-none'); // 隐藏

}

else {

$("#categoryRow").removeClass('d-none'); //显示

}

$('#CategoryId').empty();

$.each(data,

function (id, option) {

$('#CategoryId').append($('<option></option>').val(option.value).html(option.text));

});

}

});

});

//班级下拉框控件联动局部刷新学生下拉框控件。

$('#CategoryId').on('change', function () {

var categaryId = $(this).val();

$.ajax({

url: "/LogicRender/StudentSelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"categaryId": categaryId,

},

success: function (data) {

if (categaryId == 0) {

$("#studentRow").addClass('d-none'); // 隐藏

}

else {

$("#studentRow").removeClass('d-none'); //显示

}

$('#StudentId').empty();

$.each(data,

function (id, option) {

$('#StudentId').append($('<option></option>').val(option.value).html(option.text));

});

}

});

});

//学生下拉框控件联动局部刷新学生编号控件。

$('#StudentId').on('change', function () {

var studentId = $(this).val();

$.ajax({

url: "/LogicRender/CodeSelectListAjax",

type: "POST",

datatype: "JSON",

cache: false,  //禁用缓存。

data:

{

"studentId": studentId,

},

success: function (data) {

if (studentId == 0) {

$("#codeRow").addClass('d-none'); // 隐藏

}

else {

$("#codeRow").removeClass('d-none'); //显示

}

$('#Code').val(data);

}

});

});

//在数据持久化到指定表后,自动通过父窗口中指定按钮标签的单击事件,自动关闭当前弹出窗口。

if ("@ViewBag.RefreshPage" == "True") {

//获取父窗口中指定按钮标签。

//window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

window.opener.$("#@Context.Request.Query["btnId"]").click();

window.close();

}

</script>

}

3.2.5 内存逻辑分页,之DataTable渲染显示原理

对以上功能更为具体实现和注释见:22-10-06-05_SqlSugarAcquaintance(初识SqlSugarCore之内置逻辑分页)。

第5章 初识SqlSugarCore之内置逻辑分页相关推荐

  1. 第9章 初识SqlSugarCore之AutoMapper

    1 AutoMapperExtensions(以泛型形式,扩展) using AutoMapper; namespace Web.Extensions { /// <summary> // ...

  2. c生万物【第一章 初识c语言】

    c生万物---第一章 初识c语言 前言 1.什么是C语言 2.第一个C语言程序 3.数据类型 4.变量.常量 4.1定义变量的方法 4.2变量的分类 4.3变量的使用 4.4 变量的作用域和生命周期 ...

  3. 【转载】JAVAEE之内置对象和属性范围

    原文:JAVAEE之内置对象和属性范围 内置对象和属性范围 ​ 四种属性范围 ​ 九个内置对象 1.内置对象 如果说想要使用一个对象,必须new 出来,但是在我们的jsp操作中,发现我们使用过的out ...

  4. Hadoop权威指南 _03_第I部分Hadoop基础知识_第1章初识Hadoop.

    第I部分Hadoop基础知识 第1章初识Hadoop. 比较喜欢这句极其形象的比喻. "在古时候,人们用牛来拉重物.当一头牛拉不动根圆木时,人们从来没有考虑过要想方设法培育出一种更强壮的牛. ...

  5. 第一章 初识Mathematica

    第一章  初识Mathematica   1.Mathematica是什么 Matematica是由美国Wolfram公司研究开发的一个著名的数学软件,它提供了非常强大的功能,能够完成符号运算.数学图 ...

  6. 《Python爬虫开发与项目实战》——第3章 初识网络爬虫 3.1 网络爬虫概述

    本节书摘来自华章计算机<Python爬虫开发与项目实战>一书中的第3章,第3.1节,作者:范传辉著,更多章节内容可以访问云栖社区"华章计算机"公众号查看 第3章 初识网 ...

  7. 《开源硬件创客——15个酷应用玩转树莓派》——第1章 初识树莓派

    本节书摘来异步社区<开源硬件创客--15个酷应用玩转树莓派>一书中的第1章,作者:朱铁斌,更多章节内容可以访问云栖社区"异步社区"公众号查看 第1章 初识树莓派 开源硬 ...

  8. python中递归函数的基例_详谈Python基础之内置函数和递归 Python递归和循环的区别...

    Python 递归函数基例 2. 关于递归函数基例的说明,以下选项中错误的是 A 递归函数的基例决定所谓基例就是不需要递归就能求解的,一般来说是问题的最小规模下的解. 例如:斐波那契数列递归,f(n) ...

  9. 《起跑吧,Opa》 -- 中译本 第一章 初识Opa

    第一章 初识opa 本章,你将初识opa.你将学习如何安装Opa,编写opa程序以及熟悉Opa开发周期中的各个步骤. 安装opa 需要你预先从opa网站(http://opalang.org/)下载适 ...

  10. 第一章 初识EmguCV

    第一章 初识EmguCV 1.1 EmguCV的基本介绍 1.1.1 计算机视觉.OpenCV和EmguCV 计算机视觉是一门研究如何使机器"看"的科学,更进一步的说,就是是指用摄 ...

最新文章

  1. [vb+mo] visual baisc 6.0 基于mapobjects 2.4 开发的数字化校园电子地图
  2. 用户故事为什么要关联开发数据?
  3. 豆瓣评分 9.0,超 10 万开发者的入门选择,这本经典好书终于升级啦!
  4. Python处理大数据
  5. java -jar Incompatible argument to function
  6. vs code配置python环境mac_mac vscode Python配置
  7. [Java]Stack栈和Heap堆的区别(终结篇)[转]
  8. 利用HAProxy实现零停机更新维护
  9. CTFshow php特性 web113
  10. Spring JPA使用CriteriaBuilder动态构造查询
  11. Scala集合:List增加元素及集合拼接操作
  12. T-SQL RAND()
  13. scp和sftp常用操作
  14. python 系统当前时间向前推2天_当前日期往前推N天,当前日期往后推N天
  15. linux系统之编译内核实现iptables应用层过滤
  16. HDU 5281 Senior's Gun 贪心
  17. [转]Android的Handler总结
  18. c# 正则表达式对网页进行有效内容抽取
  19. StretchDIBits绘制原始YUV异常
  20. 一篇可以终结房价涨跌讨论的文章(…

热门文章

  1. 西边人西说测试,测试蓝本 | 一篇文章看懂什么是测试,测试是干什么的
  2. DRILLNET 2.0------第十三章 尾管固井扭矩/摩阻模型
  3. OpenCV蒙版的使用实例(1)
  4. html加载fbx模型,[Unity菜鸟] FBX模型动画提取
  5. Oracle用户管理的备份与恢复(冷热)
  6. 计算机删除用户8,Win8.1如何删除账户?
  7. 加拿大前十大学计算机硕士学费,2018年加拿大各大学硕士学费一览表!
  8. C语言-基础入门-学习笔记(13):结构体
  9. 关闭浏览器自动退出账号
  10. java abs是什么意思_Java abs()方法