Как получить записи для верхнего родителя в наборе данных?

#c# #asp.net #.net #asp.net-core #.net-core

Вопрос:

Мне был предоставлен набор данных, содержащий данные в приведенном ниже формате.

Мне нужно вернуть сведения о категории для данной категории. Если ключевое слово отсутствует для категории, то необходимо вернуть ключевые слова родителя верхнего уровня. родительский элемент верхнего уровня-это категория, для которой родительская категория равна -1.

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

ParentCategoryID=201, Имя=Операционная система, Ключевые слова=Обучение

введите описание изображения здесь

Я получаю записи из приведенного ниже кода.

 string queryString = "SELECT [Category Id],[Parent Category Id],[Name],[Keywords] FROM [dbo].[Categories]";

SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlDataAdapter adapter = new SqlDataAdapter(queryString, sqlConnection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Categories");
 

Я могу написать логику, чтобы получить главного родителя в списке из приведенного ниже кода. но я не могу написать его в соответствии с требованиями к набору данных.

 public long GetParent(long category)
{
    var element = ls.FirstOrDefault(x => x.Category == category);

    if(element.ParentCategory == -1)
    {
        return category;
    }

    return GetParent(element.ParentCategory);
}
 

Примечание: в таблице могут быть миллионы записей.

Комментарии:

1. Непонятно, что вам нужно. Измените свой sql-запрос, чтобы эта логика присутствовала в базе данных, или измените набор данных, чтобы при необходимости вы обновили его ключевыми словами из верхней категории. Если первое, вам нужно включить гораздо больше, начиная с используемой СУБД и всех таблиц, включая их схему. Если последнее, вы должны сказать, почему ваш код не работает, если вы просто зацикливаете все строки.

2. Мне нужно обработать это на C#, а не в базе данных.

Ответ №1:

Попробуйте следовать рекурсивному методу

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication
{
    public class Program
    {
        static DataTable dt = null;
        public static void Main(string[] args)
        {
            dt = new DataTable();
            dt.Columns.Add("Category Id", typeof(long));
            dt.Columns.Add("Parent Category Id", typeof(long));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Keywords", typeof(string));

            dt.Rows.Add(new object[] { 100, -1, "Business", "Money" });
            dt.Rows.Add(new object[] { 200, -1, "Tutoring", "Teaching" });
            dt.Rows.Add(new object[] { 101, 100, "Accounting", "Taxes" });
            dt.Rows.Add(new object[] { 102, 100, "Taxation"});
            dt.Rows.Add(new object[] { 201, 200, "Computer"});
            dt.Rows.Add(new object[] { 103, 101, "Computer Tax"});
            dt.Rows.Add(new object[] { 202, 201, "Operating System"});
            dt.Rows.Add(new object[] { 109, 101, "Small Business Tax"});

            DataRow row = dt.AsEnumerable().Where(x => x.Field<long>("Category Id") == 202).FirstOrDefault();
            DataRow parentId = GetParent(row);
            string results = "";
            if (parentId != null)
            {
                results = string.Join(",", parentId.ItemArray);
            }
        }

        static DataRow GetParent(DataRow row)
        {
            DataRow parent = null;
            long pCategory = row.Field<long>("Parent Category Id");

            DataRow parentRow = dt.AsEnumerable().Where(x => x.Field<long>("Category Id") == pCategory).FirstOrDefault();

            if (parentRow != null)
            {
                parent = GetParent(parentRow);
            }
            else
            {
                parent = row;
            }

            return parent;
        }
    }

}
 

Вот тестирование на -1

        static DataRow GetParent(DataRow row)
        {
            DataRow parent = null;
            long pCategory = row.Field<long>("Parent Category Id");

            DataRow parentRow = dt.AsEnumerable().Where(x => x.Field<long>("Category Id") == pCategory).FirstOrDefault();
            long parentCategory = parentRow.Field<long>("Parent Category ID");

            if (parentCategory != -1)
            {
                parent = GetParent(parentRow);
            }
            else
            {
                parent = parentRow;
            }

            return parent;
        }
 

Комментарии:

1. Верхний уровень определяется на основе значения идентификатора родительской категории -1

2. Мои нули работают одинаково, так как нет категории с идентификатором -1.

3. Я добавил тестирование решения для -1.