Я новичок в ASP.NET Core, работаю над проектом ASP.NET Core, и мне нужно использовать таблицу данных, которая получает данные с сервера sql. У меня нет проблем в случаях, когда нет дочерних строк, но я должен отображать данные с несколькими дочерними строками. Я не могу показывать данные с дочерними строками. есть много примеров с ajax, но я не смог найти ни одного примера данных с сервера sql в ядре asp.net.
Если говорить кратко о структуре базы данных, то есть 2 таблицы: Order и OrderList.
Заказ: OrderId (PK-int), Заказчик (строка), OrderDate (дата и время)
OrderList:KimlikId(PK-int),OrderId(int),Product(string),Color(string),Qntty(int)
Заказ INNER JOIN OrderList ON Order.OrderId = OrderList.OrderId
Мой класс Model OrderList выглядит следующим образом:
public class OrderList
{
public int OrderId { get; set; }
public int KimlikId { get; set; }
public string Customer { get; set; }
public string OrderDate { get; set; }
public string Product { get; set; }
public string Color { get; set; }
public int Qntty { get; set; }
}
Мой класс контроллера OrderController выглядит следующим образом:
public class OrderController : Controller
{
public IEnumerable<OrderList> GetAllOrderList()
{
string connectionString = "My Connection String of sql server";
List<OrderList> sipList = new List<OrderList>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("SELECT * FROM Order INNER JOIN OrderList ON Order.OrderId = OrderList.OrderId ORDER BY OrderList.OrderId DESC;", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
OrderList sip = new OrderList();
sip.OrderId = Convert.ToInt32(dr["OrderId"].ToString());
sip.Customer = dr["Customer"].ToString();
sip.OrderDate = DateTime.Parse(dr["OrderDate"].ToString()).ToString("dd/MM/yyyy");
sip.Product = dr["Product"].ToString();
sip.Color = dr["Color"].ToString();
sip.Qntty = Int32.Parse(dr["Qntty"].ToString());
sipList.Add(sip);
}
con.Close();
}
return sipList;
}
public IActionResult OrderIndex()
{
List<OrderList> sipList = new List<OrderList>();
sipList = GetAllOrderList().ToList();
return View(sipList);
}
}
Мой вид - это OrderIndex.cshtml, например:
@model IEnumerable<AlplerCRM.Models.OrderList>
@{
ViewData["Title"] = "Ordesr";
Layout = "~/Views/Shared/_AnaLayout.cshtml";
}
<table id = "example" class = "display" style = "width:100%">
<thead>
<tr>
<th></th>
<th>OrderId</th>
<th>Customer</th>
<th>OrderDate</th>
</tr>
</thead>
</table>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
function format(d) {
return '<table id = "childtable" cellpadding = "5" cellspacing = "0" border = "0" style = "padding-left: 50px; ">' +
'<tr>' +
'<td>Kimlik No</td>' +
'<td>Product Detail</td>' +
'<td>Product Color</td>' +
'<td>Product Quantity</td>' +
'</tr><tr>' +
'<td>' + d.KimlikId + '</td>' +
'<td>' + d.Product + '</td>' +
'<td>' + d.Color + '</td>' +
'<td>' + d.Qntty + '</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
var table = $("#example").dataTable({
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "OrderId" },
{ "data": "Customer" },
{ "data": "OrderDate" },
],
"order": [[0, 'desc']]
});
});
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
</script>
}
Как я могу получить данные без ajax и показать данные следующим образом:
Вы имели в виду, что уже получили результат, представленный на скриншоте (используя JQuery ajax и плагин JQuery dataTable, Ajax используется для загрузки данных из контроллера), и теперь вы не хотите использовать Ajax для загрузки данных? Если это так, вы можете передать данные для просмотра с помощью ViewData или ViewBag, а затем на странице просмотра использовать следующий код, чтобы получить значение: var data = JSON.parse('@Html.Raw(ViewData["json"])'); //json string var items = JSON.parse('@Html.Raw(JsonSerializer.Serialize(ViewData["data"]))'); //object list
. Затем вы можете отображать данные с помощью плагина jquery datatable.
снимок экрана — это просто иллюстрация к моей цели, из базы данных будут поступать тысячи данных. Я думаю, мне нужно загрузить с помощью Ajax. Есть так много примеров datatable с ajax, получая 1 данные таблицы базы данных, но мне нужно получить данные с Ajax, получив данные объединения 2 таблиц.
Вот относительно простой способ, которым я это сделал.
Я использую скрытую строку под «родительской» строкой, которая расширяет полное количество ячеек и отображается/скрывается с помощью события щелчка div в родительской ячейке. Этот div содержит атрибут data-id
для значения идентификатора заказа строки, который я использую для создания ссылки (например, detail_151) на дочернюю/скрытую строку. Конечно, это предполагает, что родительские идентификаторы уникальны. Вы можете добавить эти значения при создании исходного HTML-кода.
См. мой фрагмент для примера.
// Add the .expand class click events once the page is loaded.
window.onload = e => {
document.querySelectorAll('.expand').forEach(div => {
div.addEventListener('click', e => {
// Toggle the detail display.
const detail = document.querySelectorAll(`#detail_${e.target.getAttribute('data-id')}`)[0];
if (detail.classList.contains('hide'))
detail.classList.remove('hide');
else
detail.classList.add('hide');
});
});
}
body {
font-size: 1em;
}
th,
td {
position: relative;
width: 125px;
text-align: left;
}
.expand {
position: absolute;
font-size: 1.4em;
margin-top: -5px;
margin-left: -20px;
color: green;
font-weight: bold;
cursor: pointer;
}
.hide {
display: none;
}
.show {
display: block;
}
<table style = "margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th>OrderId</th>
<th>Customer</th>
<th>OrderDate</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div data-id = "151" class = "expand">+</div>151</td>
<td>Customer21</td>
<td>22.12.2020</td>
</tr>
<tr id = "detail_151" class = "hide">
<td colspan = "3">
<table>
<tr>
<th>Kimlik</th>
<th>Detail</th>
<th>Color</th>
<th>Qty</th>
</tr>
<tr>
<td>2114</td>
<td>Product-14</td>
<td>Green</td>
<td>3</td>
</tr>
<tr>
<td>2358</td>
<td>Product-48</td>
<td>Yellow</td>
<td>2</td>
</tr>
<tr>
<td>2365</td>
<td>Product-08</td>
<td>Red</td>
<td>6</td>
</tr>
<tr>
<td>2371</td>
<td>Product-33</td>
<td>Red</td>
<td>1</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<div data-id = "155" class = "expand">+</div>155</td>
<td>Customer18</td>
<td>22.12.2020</td>
</tr>
<tr id = "detail_155" class = "hide">
<td colspan = "3">
<table>
<tr>
<th>Kimlik</th>
<th>Detail</th>
<th>Color</th>
<th>Qty</th>
</tr>
<tr>
<td>2019</td>
<td>Product-11</td>
<td>Red</td>
<td>3</td>
</tr>
<tr>
<td>2110</td>
<td>Product-17</td>
<td>Blue</td>
<td>5</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
скриншот - это просто иллюстрация к моей цели, из базы данных будут поступать тысячи данных
Основываясь на вашем коде и описании, я предлагаю вам выполнить следующие шаги для отображения результата.
Создайте следующую модель представления, она используется для привязки данных к плагину JQuery DataTable.
public class OrderListViewModel
{
public int OrderId { get; set; }
public string Customer { get; set; }
public string OrderDate { get; set; }
public List<OrderListDetailViewModel> OrderListDetails { get; set; }
}
public class OrderListDetailViewModel
{
public int KimlikId { get; set; }
public string Product { get; set; }
public string Color { get; set; }
public int Qntty { get; set; }
}
Добавьте следующий метод действия: вызовите метод GetAllOrderList(), чтобы получить весь список OrderList, а затем с помощью операторов GroupBy сгруппируйте результат (на основе внешних свойств: OrderId, Customer и OrderDate).
public IEnumerable<OrderListViewModel> GetOrderList()
{
return GetAllOrderList().GroupBy(c => new { c.OrderId, c.Customer })
.Select(c => new OrderListViewModel()
{
OrderId = c.Key.OrderId,
Customer = c.Key.Customer,
OrderDate = c.FirstOrDefault().OrderDate,
OrderListDetails = c.Select(d => new OrderListDetailViewModel() { Qntty = d.Qntty, Color = d.Color, KimlikId = d.KimlikId, Product = d.Product }).ToList()
}).ToList();
}
используя следующий код для вызова вышеуказанного метода действия и отображения результата (код на странице Index.cshtml):
<link href = "https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css" rel = "stylesheet" />
<style>
td.details-control { background: url('https://datatables.net/examples/resources/details_open.png') no-repeat center center; cursor: pointer; }
tr.shown td.details-control { background: url('https://datatables.net/examples/resources/details_close.png') no-repeat center center; }
</style>
<table id = "example" class = "display" style = "width:100%">
<thead>
<tr>
<th></th>
<th>OrderId</th>
<th>Customer</th>
<th>OrderDate</th>
</tr>
</thead>
</table>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src = "https://code.jquery.com/jquery-3.5.1.js"></script>
<script src = "https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<script>
function format(d) {
var result = '<table id = "childtable" cellpadding = "5" cellspacing = "0" border = "0" style = "padding-left: 50px; width:80% ">' +
'<tr><td>Kimlik No</td><td>Product Detail</td><td>Product Color</td><td>Product Quantity</td></tr>';
//loop thouth the OderListDetails and add the child items.
for (var i = 0; i < d.orderListDetails.length; i++) {
var child = '<tr><td>' + d.orderListDetails[i].kimlikId + '</td>' +
'<td>' + d.orderListDetails[i].product + '</td>' +
'<td>' + d.orderListDetails[i].color + '</td>' +
'<td>' + d.orderListDetails[i].qntty + '</td></tr>';
result += child;
}
result += '</table>';
return result;
}
$(document).ready(function () {
//call the action method and get the data.
$.ajax({
url: "/Order/GetOrderList",
type: "Get",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
console.info("succsss" + data);
//after getting the data, bind the DataTable.
var table = $("#example").DataTable({
"data": data,
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "orderId" },
{ "data": "customer" },
{ "data": "orderDate" },
],
"order": [[0, 'desc']]
});
//Expand/Collapse the nested objects.
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
},
error: function (ex) {
console.info(ex);
}
});
});
</script>
}
Результат такой:
[Примечание]
dataTable()
на DataTable()
в сценарии JQuery. Более подробную информацию смотрите table.row не является функциейБолее подробную информацию об использовании плагина JQuery DataTable смотрите в документе.
Это именно то, что я хотел сделать, большое спасибо. если не слишком много, насколько доступны для поиска дочерние строки.
Я не знаю, насколько это будет эффективно, но вы можете сохранить значения дочерних строк в атрибуте
data-
родителяtr
и использовать это , как показано здесь . Но я рекомендую использовать datatable ajax для загрузки данных, так как это быстрее и проще, и у вас будет больше контроля над функциями datatable.