#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.