Я получил список категорий из БД. Далее мне нужно получить из соседней таблицы все топики, которые относятся к данной категории. После создания 2х и более записей в таблице с топиками - у меня почему-то не к категории топики прибавляются, а прибавляется категория с новым топиком. Хотя по идее Topic_Name 4 должен быть рядом с Topic_Name 3 и само собой не должно быть 2х Test Category 3.
Controller:
public async Task<IActionResult> Index()
{
var source =
from category in _context.Web_Forum_Category
join topic in _context.Web_Forum_Topic on category.Id equals topic.Category_Id
orderby topic.Id
select new IndexViewModel { Web_Forum_Category = category, Web_Forum_Topic = topic };
var model = await source.ToListAsync();
return View(model);
}
View:
@model IEnumerable<Web.Models.Web.IndexViewModel>
@foreach (var item in Model)
{
<table class="table table-condensed table-responsive">
<tbody>
<tr>
<td>
@item.Web_Forum_Category.Name_Ru @item.Web_Forum_Category.Name_En
<table>
<tbody>
<tr>
<td>@item.Web_Forum_Topic.Name</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
}
Web_Forum_Category и Web_Forum_Topic:
public class Web_Forum_Category
{
public int Id { get; set; }
public string Name_Ru { get; set; }
public string Name_En { get; set; }
}
public class Web_Forum_Topic
{
[Key]
public int Id { get; set; }
public int Category_Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
IndexViewModel
public class IndexViewModel
{
public Web_Forum_Category Web_Forum_Category { get; set; }
public Web_Forum_Topic Web_Forum_Topic { get; set; }
}
Я сначала думал что что-то с <table>...</table>
. Позже понял что увы, нет...
Оператор join
за основу берет ту коллекцию, которая указана ему с помощью in
. По этой коллекции он грубо говоря пройдется и сопоставит все значения с другой коллекцией.
Скажем если у вас в первой коллекции 10 элементов, а во второй коллекции всего два, то он выведет 10 результатов с видом который вы устанавливаете в select
. Вы же как я понял хотите сделать коллекцию категорий, которая будет содержать в себе коллекцию топиков. Для таких целей нужно еще дополнительно сгруппировать элементы, делается это с помощью group by
.
Давайте для начала я сделаю тестовые данные в своем консольном приложение и попробуем поиграться с ними:
var cat = new List<Web_Forum_Category>
{
new Web_Forum_Category(1, "Тестовая категория 1", "Test category 1"),
new Web_Forum_Category(2, "Тестовая категория 2", "Test category 2"),
new Web_Forum_Category(3, "Тестовая категория 3", "Test category 3")
};
var top = new List<Web_Forum_Topic>
{
new Web_Forum_Topic(1, 1, "Тестовый топик 1", "Описание"),
new Web_Forum_Topic(2, 2, "Тестовый топик 2", "Описание"),
new Web_Forum_Topic(3, 1, "Тестовый топик 3", "Описание"),
new Web_Forum_Topic(4, 3, "Тестовый топик 4", "Описание")
};
var source =
from category in cat
join topic in top on category.Id equals topic.Category_Id
orderby topic.Id
select new { Web_Forum_Category = category, Web_Forum_Topic = topic };
var model = source.ToList();
foreach (var item in model)
{
Console.WriteLine($"{item.Web_Forum_Category.Name_Ru} | {item.Web_Forum_Category.Name_En}");
Console.WriteLine(item.Web_Forum_Topic.Name);
}
Результат как и у вас:
Тестовая категория 1 | Test category 1
Тестовый топик 1
Тестовая категория 2 | Test category 2
Тестовый топик 2
Тестовая категория 1 | Test category 1
Тестовый топик 3
Тестовая категория 3 | Test category 3
Тестовый топик 4
Теперь сгруппируем это:
var source =
from topic in top
group topic by topic.Category_Id into g
join category in cat on g.Key equals category.Id
select new {Web_Forum_Category = category, Web_Forum_Topic = g.ToList()};
var model = source.ToList();
Теперь Web_Forum_Topic
будет содержать не один элемент, а коллекцию топиков и для вывода нам потребуется пройтись и по ней циклом тоже:
foreach (var item in model)
{
Console.WriteLine($"{item.Web_Forum_Category.Name_Ru} | {item.Web_Forum_Category.Name_En}");
item.Web_Forum_Topic.ForEach(x=>Console.WriteLine(x.Name));
}
Вывод:
Тестовая категория 1 | Test category 1
Тестовый топик 1
Тестовый топик 3
Тестовая категория 2 | Test category 2
Тестовый топик 2
Тестовая категория 3 | Test category 3
Тестовый топик 4
Вообще, я очень сильно не люблю такой вид LINQ, ведь написать что то по типу:
var source = cat.GroupJoin(top, c => c.Id, t => t.Category_Id,
(category, topics) => new {Web_Forum_Category = category, Web_Forum_Topic = topics.ToList()});
куда приятней... Но это пожалуй решать каждому...
В общем удачи в изучении!
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как вставить код символа в запрос С#? В месте, где я указываю на формат даты:
Вопрос теоретический, делал я задачу тестовую для VeeamЗнаменитая задача про архиватор многопоточный