Несколько дочерних строк в datatable, данные с сервера sql в ядре asp.net

Я новичок в 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 и показать данные следующим образом:

Я не знаю, насколько это будет эффективно, но вы можете сохранить значения дочерних строк в атрибуте data- родителя tr и использовать это , как показано здесь . Но я рекомендую использовать datatable ajax для загрузки данных, так как это быстрее и проще, и у вас будет больше контроля над функциями datatable.

Pirate 22.12.2020 15:50

Вы имели в виду, что уже получили результат, представленный на скриншоте (используя 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["dat‌​a"]))'); //object list. Затем вы можете отображать данные с помощью плагина jquery datatable.

Zhi Lv 23.12.2020 10:06

снимок экрана — это просто иллюстрация к моей цели, из базы данных будут поступать тысячи данных. Я думаю, мне нужно загрузить с помощью Ajax. Есть так много примеров datatable с ajax, получая 1 данные таблицы базы данных, но мне нужно получить данные с Ajax, получив данные объединения 2 таблиц.

halil balcıoğlu 23.12.2020 11:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
3
3 118
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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>

скриншот - это просто иллюстрация к моей цели, из базы данных будут поступать тысячи данных

halil balcıoğlu 23.12.2020 11:31
Ответ принят как подходящий

Основываясь на вашем коде и описании, я предлагаю вам выполнить следующие шаги для отображения результата.

  1. Создайте следующую модель представления, она используется для привязки данных к плагину 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; }
     }
    
  2. Добавьте следующий метод действия: вызовите метод 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();
     }
    
  3. используя следующий код для вызова вышеуказанного метода действия и отображения результата (код на странице 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>
     }
    

Результат такой:

[Примечание]

  • Если вы столкнулись с ошибкой «table.row не является функцией», измените dataTable() на DataTable() в сценарии JQuery. Более подробную информацию смотрите table.row не является функцией
  • При привязке данных к плагину JQuery DataTable не забудьте изменить первый символ свойств на нижний регистр.

Более подробную информацию об использовании плагина JQuery DataTable смотрите в документе.

Это именно то, что я хотел сделать, большое спасибо. если не слишком много, насколько доступны для поиска дочерние строки.

halil balcıoğlu 24.12.2020 15:31

Другие вопросы по теме