開發工具與關鍵技術:Visual Studio 2015 LINQ
作者:孫水兵
撰寫時間:2019年6月3
一、 達到的效果
在數據表格中要有線路名稱、線路表號、起點站編號、起點站名稱、終點站編號、終點站名稱、里程、方向、所屬車站編號、所屬車站信息、所屬區域、備註、停開這些字段的數據。除此之外,在數據表格的上方有一個線路編號/名稱的input框,可以在input框中輸入線路編號或者名稱然後點擊查詢,可以查出相對應的數據。
二、 涉及到的表格:線路表(SYS_Circuit)、站點表(SYS_Station )、站點明細表(SYS_StationDetail)、線路站點類型表(SYS_CircuitStationType)
在這些表格中,線路表、站點表、線路站點類型表都是根據站點明細表連接起來的,其中線路站點類型表中的線路站點類型ID(CircuitStationTypeID)等於1時,表示的站點類型爲起點站,線路站點類型表中的線路站點類型ID(CircuitStationTypeID)等於2時,表示的站點類型爲終點站。
三、 代碼(建議和我以前的文章:簡單使用layui完成數據表格對比查看)
HTML代碼
HTML代碼只需要在合適的地方放置一個table標籤,id和lay-filter都寫上即可。查詢按鈕和查詢的input框另外寫。
<div class="container-fluid">
<div class="row">
<!--線路信息-->
<div class="col-12 p-1 ">
<div class="card" id="Circuit">
<div class="card-header"><span>線路詳細情況</span></div>
<div class="card-body pt-2">
<div class="row pl-5 flex-lg-wrap mt-2">
<div class="col-10">
<form class="form-inline form-row">
<label class="col-form-label mr-2" for="searchPlanCircuitCode">線路編號/名稱:</label>
<input class="form-control form-control-sm mr-3" id="searchPlanCircuitCode" name="searchPlanCircuitCode" />
@*在超小(手機等移動端)上強制換行並設置邊距*@
<div class="w-100 mb-2 d-inline d-sm-none"></div>
@*按鈕組*@
<div class="form-group">
<button type="button" class="btn btn-sm btn-primary mr-4" onclick="searchTabCircuit()">查詢</button>
<button type="button" class="btn btn-sm btn-primary mr-lg-3" id="InsertCircuit">添加</button>
<button type="button" class="btn btn-sm btn-primary mr-4">打印</button>
<button type="button" class="btn btn-sm btn-danger mr-4 " onclick="deleteCircuit()">批量刪除</button>
</div>
</form>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm btn-secondary" id="quit"><i class="zi zi_circleLeftLong m-1" zico="指左圓箭頭長"></i>退出</button>
</div>
</div>
<div class="row">
<div class="col-12">
<table id="tabCircuit" lay-filter="tabCircuit"></table>
</div>
</div>
</div>
</div>
</div>
</div>
JS代碼
關於如何用layui插件搭建基礎的數據表格可以查看我以前的文章:簡單使用layui完成數據表格。稍微有點不同的是這裏涉及到了條件查詢,要使用layui中table模塊中的表格重載。因此需要在表格的分頁的下方加上data[],除此之外還需要將表格中的URL註釋或者剪切到表格重載中。在條件查詢的方法中獲取到查詢的input框的值並用searchCircuitNameNum接收,然後判斷searchCircuitNameNum是否爲undefined,如果是,讓searchCircuitNameNum爲空字符串。然後調用表格的重載,在重載的方法中調用控制器中查詢的方法,利用where將獲取到的searchCircuitNameNum的值傳入控制器。Page:{curr:1}表示重新從第一頁開始。(建議先從數據庫中查出了數據在寫條件查詢)
$(function () {
layui.use(['layer', 'table'], function () {
layer = layui.layer;
layuiTable = layui.table;
layuiForm = layui.form;
//線路表
tabCircuit = layuiTable.render({
elem: "#tabCircuit",
//url: "/BusinessManagement/CircuitManagement/SelectCircuitAll",
cellMinWidth: 80,
cols: [[
{ type: 'checkbox' },
{ type: 'numbers', title: '序號' },
{ field: 'CircuitID', title: 'CircuitID', hide: true },//hide:true 隱藏列
{ field: 'CircuitName', title: '線路名稱', align: 'center' },
{ field: 'CircuitNumber', title: '線路編號', align: 'center' },
{ field: 'StartStationCode', title: '起點站編號', align: 'center' },
{ field: 'StartStationName', title: '起點站名稱', align: 'center' },
{ field: 'EndStationCode', title: '終點站編號', align: 'center' },
{ field: 'EndStationName', title: '終點站名稱', align: 'center' },
{ field: 'CircuitMileage', title: '里程', width: 60, align: 'center' },
{ field: 'CircuitDirection', title: '方向', width: 60, align: 'center' },
{ field: 'PassengerStationCode', title: '所屬車站編號', align: 'center', width: 120 },
{ field: 'PassengerStationName', title: '所屬車站名稱', align: 'center', width: 120 },
{ field: 'AreaName', title: '所屬區域', align: 'center' },
{ field: 'CircuitRemark', title: '備註', align: 'center', width: 80 },
{ title: '停開', templet: StopCircuit, align: 'center', fixed: 'right', width: 60 },
{ title: '操作', templet: setOperateCircuit, align: 'center', fixed: 'right', width: 150 }
]], //開啓分頁
page: {
limit: 5,//指定每頁顯示的條數
limits: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50],//每頁條數的選擇項
},
data: [],
})
//線路表監聽單行點擊事件(雙擊事件爲:rowDouble)
layuiTable.on('row(tabCircuit)', function (obj) {
var data = obj.data;
//標中選中行樣式
obj.tr.addClass('layui-table-click').siblings().removeClass('layui-table-click');
//選中行,勾選複選框
obj.tr.find("div.layui-unselect.layui-form-checkbox")[0].click();
var CircuitID = obj.data.CircuitID;
tabHighwaySection.reload({
url: "/BusinessManagement/CircuitManagement/selectHighWaySection",
where: {
CircuitID: CircuitID
},
page: {
curr: 1
}
});
});
//調用多條件查詢方法
searchTabCircuit();
})
});
//多條件查詢
function searchTabCircuit() {
var searchCircuitNameNum = $("#searchPlanCircuitCode").val();
if (searchCircuitNameNum == undefined) {
searchCircuitNameNum = "";
}
tabCircuit.reload({
url: "/BusinessManagement/CircuitManagement/SelectCircuit",
where: {
searchCircuitNameNum: searchCircuitNameNum
},
page: {
curr: 1
}
});
}
控制代碼
在寫控制器中的代碼時要先判斷你需要的字段是否都在一個表格中,如果在,那就可以直接寫,如果不在,需要先添加一個類CircuitVo。在類名的後面可以繼承主要表的所有字段,然後將主要表格中沒有的字段在類中寫上。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TransportManagment.Models;
namespace TransportManagment.EntityClass
{
public class CircuitVo:SYS_Circuit
{
/// <summary>
/// 起點站編號
/// </summary>
public string StartStationCode { get; set; }
/// <summary>
/// 起點站名稱
/// </summary>
public string StartStationName { get; set; }
/// <summary>
/// 終點站編號
/// </summary>
public string EndStationCode { get; set; }
/// <summary>
/// 終點站名稱
/// </summary>
public string EndStationName { get; set; }
/// <summary>
/// 所屬區域
/// </summary>
public string AreaName { get; set; }
/// <summary>
/// 所屬車站編號
/// </summary>
public string PassengerStationCode { get; set; }
/// <summary>
/// 所屬車站名稱
/// </summary>
public string PassengerStationName { get; set; }
/// <summary>
/// 起點站ID
/// </summary>
public int StartStationID { get; set; }
/// <summary>
/// 終點站ID StationDetail
/// </summary>
public int EndStationID { get; set; }
public int StationDetailID { get; set; }
public int StartStationDetailID { get; set; }
}
}
完成CircuitVo之後,創建方法,string searchCircuitNameNum是用來接收數據庫傳過來的查詢的條件(建議寫完查詢後在寫條件查詢)。由於這裏查詢的時候起點站和終點站都是在站點表中,直接查詢的話不好直接同時查詢出起點站和終點站。因此在查詢線路數據之前先使用group…by 在站點明細表中根據線路ID(CircuitID)分組查詢。group tbStationDetail by tbStationDetail.CircuitID into tbStation:表示對tbStationDetail按CircuitID進行分組,其結果命名爲tbStation。然後查詢,key屬性:返回進行分組的關鍵字段的值;在這指的是tbStationDetail.CircuitID。上面提到CircuitStationTypeID等於1時,站點爲起點站,等於2時,站點爲終點站。起點站的ID等於分組之後的第一條數據的站點ID,終點站的ID爲分組後根據站點類型ID進行倒序排序之後的第一條數據的站點ID。這樣,就將每一條線路的起點站和終點站分隔開。
將起點站和終點站處理好了之後就可以進行數據的查詢了。首先從上方查詢出來的數據中查詢,跟後連接線路表、區域表、車站表和站點表查詢數據。需注意的是,連接站點表的時候要連接兩次,分別是根據上面查出來的起點站ID和終點站ID來連表查詢,最後插敘出自己需要的數據。可能是由於使用了分組的原因,每次查詢出來的數據都會重複,因此在ToLost()前面加上Distnict()來去除重複的數據。至於排序呢,我預想的是所有線路狀態爲false和所有線路狀態爲true的分隔開來並且新增的數據在所在狀態的第一條數據。因此,我先根據線路狀態進行倒序排序,然後根據線路ID進行倒序排序。然後就是條件查詢了,先判斷view傳過來的數據是否爲空,如果不爲空,再在查出來的所有的數據中進行條件查詢。查出來的所有的數據中的線路名稱(CircuitName)或者線路編號(CircuitNumber)的內容存在與傳過來的條件相同的內容的所有數據。剩下的和我以前的文章:簡單使用layui完成數據表格中的內容一致。
public ActionResult SelectCircuit(LayuiTablePage layuiTablePage, string searchCircuitNameNum)
{
var linqCircuit = from tbStationDetail in myModels.SYS_StationDetail
group tbStationDetail by tbStationDetail.CircuitID into tbStation
select new
{
CircuitID = tbStation.Key,
StartStationID = tbStation.FirstOrDefault().StationID,
EndStationID = tbStation.OrderByDescending(m => m.CircuitStationTypeID).FirstOrDefault().StationID,
};
List<CircuitVo> CircuitAll1 = (from tblinqCircuit in linqCircuit
join tbCircuit in myModels.SYS_Circuit on tblinqCircuit.CircuitID equals tbCircuit.CircuitID
join tbStartStation in myModels.SYS_Station on tblinqCircuit.StartStationID equals tbStartStation.StationID
join tbEndStation in myModels.SYS_Station on tblinqCircuit.EndStationID equals tbEndStation.StationID
join tbArea in myModels.SYS__Area on tbCircuit.AreaID equals tbArea.AreaID
join tbPassengerStation in myModels.SYS_PassengerStation on tbCircuit.PassengerStationID equals tbPassengerStation.PassengerStationID
select new CircuitVo
{
CircuitID = tbCircuit.CircuitID,
AreaID = tbCircuit.AreaID,
PassengerStationID = tbCircuit.PassengerStationID,
CircuitName = tbCircuit.CircuitName,
CircuitNumber = tbCircuit.CircuitNumber,
StartStationCode = tbStartStation.StationCode,
StartStationName = tbStartStation.StationName,
EndStationCode = tbEndStation.StationCode,
EndStationName = tbEndStation.StationName,
CircuitMileage = tbCircuit.CircuitMileage,
CircuitDirection = tbCircuit.CircuitDirection,
PassengerStationCode = tbPassengerStation.PassengerStationCode,
PassengerStationName = tbPassengerStation.PassengerStationName,
AreaName = tbArea.AreaName,
CircuitRemark = tbCircuit.CircuitRemark,
CircuitToVoidNo = tbCircuit.CircuitToVoidNo
}).Distinct().ToList();
//排序
List<CircuitVo> CircuitAll = CircuitAll1.OrderByDescending(m => m.CircuitToVoidNo).ThenByDescending(m => m.CircuitID).ToList();
if (!string.IsNullOrEmpty(searchCircuitNameNum))
{
CircuitAll = CircuitAll.Where(m => m.CircuitName.Contains(searchCircuitNameNum) || m.CircuitNumber.Contains(searchCircuitNameNum)).ToList();
}
int total = CircuitAll.Count();
List<CircuitVo> list = CircuitAll
.Skip(layuiTablePage.GetStartIndex())
.Take(layuiTablePage.limit)
.ToList();
LayuiTableData<CircuitVo> layuiTableData = new LayuiTableData<CircuitVo>
{
count = total,
data = list
};
return Json(layuiTableData, JsonRequestBehavior.AllowGet);
}