Diskuze: Výpis podkategorií
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Zobrazeno 18 zpráv z 18.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Jde ti o to mit kategorii, ktera ma pak n podkategorii? Co ti brani udelat nasledujici? Viz
public class Section
{
public int ID { get; set; }
public string Name { get; set; }
public List<Category> Categories { get; set; }
}
public class Category
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Content { get; set; }
}
Pak si v DbContextu udelas vazby a proste je plnis. V cem je konkretne problem?
Ahoj, to co hledáš je rekurze, buď si ji můžeš udělat v C# viz. třeba. … sice v javě (C# je hodně podobný)
nebo
MSSQL podporuje tuším od verze 2008 rekurzivní SQL dotazy... Viz. třeba...
To ti pomůže vytvořit tebou požadované podklady pro menu.
Ahoj,
don.jardacius má pravdu. Ten MS SQL Server to nativně umí od verze 2005 a ve
verzi MSSQLServer2016 jde ještě o hodně dále. Také to umí MariaDB, která
je zdarma dostupná jako XAMPP ( https://www.apachefriends.org ).
Ještě bych dodal, že pokud to budeš chtít realizovat bez pomoci databáze, tak základní struktura (binárního) stromu má tvar:
class uzel
{
int info;
uzel levy;
uzel pravy;
}
Všem moc děkuji za odpověď.
Rekurzi znám a vím, že se to dá udělat i v MsSql. Já to dokonce
v MsSql dělám. Vrátí mi kategorii a všechny její podkategorie, to je v
pohodě. Problém ale nastává teď. Data mi přišli ve struktuře jak jsem
psal výše. A chtěl bych z toho udělat TreeMenu. A nějak jsem se do toho
zamotal a prostě nevím. Je mi jasný že tam půjde o rekurzi, ale nemůžu
nějak přijít na to jak to co nejlíp udělat. Víceméně z tohoto výstupu
budu dělat html.
<li>Kat1</li>
<li>Kat2</li>
<ul>Kat3
<li>Kat4</li>
<li>Kat5</li>
<ul>
atd. atd. Takže bych spíše potřeboval poradit jak vytvořit funkci, která mi to přežvejká a převede do následující podoby. Předem díky
V tom případě mi přijde rekurze na SQL zbytečná a udělal bych ji až
na úrovni C#, jinak by jsi ji dělal vlastně 2x.
Natáhni si z SQL pouze potřebné sloupce celého menu a udělej si rekurzi až
na úrovní C# při generování menu.
Ahoj,
kdysi jsem to dělal, tak jsem našel a lehce upravil jeden SQL kód, který
vrací hierarchii, jako asi potřebuješ. Má to chybku, že to nesetřídí
hierarchicky, ale to jde dobře dodělat.
create procedure GetFullHierarchy
(
@topic int output -- real 'selected' record
)
as
begin
begin try
begin transaction
declare @root int;
set @root = (select min(ID) from topics where UP is NULL);
if (@topic = -1) set @topic = @root;
with TopicsTemp2(ID, UP, lvl)
as
(
select ID, UP, cast(0 as int)
from topics
where ID = @root
union all
select X.ID, X.UP, cast(Y.lvl+1 as int)
from topics as X join TopicsTemp2 AS Y on X.UP = Y.ID
)
,
TopicsTemp2b(ID)
as
(
select ID
from topics
where ID = @root
union all
select X.ID
from topics as X join TopicsTemp2b AS Y on X.UP = Y.ID
)
select A.*, B.*
from TopicsTemp2 as A
left join TopicsTemp2b as B on A.ID = B.ID
join topics as C on A.ID = C.ID
-- order by lvl asc, lvlpos asc
option (maxrecursion 16);
commit transaction
set @topic = @root;
end try
begin catch
declare @systemerror int;
set @systemerror = @@ERROR;
rollback transaction;
return @systemerror;
end catch
end
go
Funguje to tak, že to získá jako parametr nebo selectem vybere root, tedy vrchol hierarchie. Od něho se potom vyberou všechny podřízené větve, do konce. Při tom se ke každému řádku počítá i odsazení pro zobrazení menu.
Moc ti děkuji za odpověď. Podívám se na to a určitě dám vedět.
Mohl by si mi prosím tě poslat
jak vypadá výstup?
Rádo se stalo.
Co se týče výstupu, ten se mi momentálně nedaří automaticky vygenerovat. Ale hlavní myšlenka je v tom prvním bloku WITH, který vytváří první virtuální tabulku TopicsTemp2, která má sloupce ID, UP a lvl (což je hloubka odsazení).
Druhý blok WITH vytváří tabulku TopicsTemp2b, která poskytuje sloupec ID. Tyto dvě virtuální tabulky (TopicsTemp2 a TopicsTemp2b) pak slouží za zdroj výslednému SELECTu na konci složeného příkazu.
Tak ještě jednou a lépe:
with TopicsTemp2(ID, UP, lvl)
as
(
select ID, UP, cast(0 as int)
from topics
where ID = @root
union all
select X.ID, X.UP, cast(Y.lvl+1 as int)
from topics as X join TopicsTemp2 AS Y on X.UP = Y.ID
)
,
TopicsTemp2b(ID)
as
(
select ID
from topics
where ID = @root
union all
select X.ID
from topics as X join TopicsTemp2b AS Y on X.UP = Y.ID
)
select A.ID, A.UP, case when B.ID is NULL then cast(1 as bit) else cast(0 as bit) end as SELECTED, A.lvl,
case
when (select count(*) from TopicsTemp2 where C.ID = UP) > cast(0 as int) or (select count(*) from topics where UP = @root AND C.ID = UP) > cast(0 as int) then cast(2 as int)
when (select count(*) from topics where C.ID = UP) > cast(0 as int) then cast(1 as int)
else cast(0 as int)
end as PACKED,
row_number() over(partition by C.UP order by TITLE) as lvlpos, C.TITLE as TopicName
from TopicsTemp2 as A
left join TopicsTemp2b as B on A.ID = B.ID
join topics as C on A.ID = C.ID
order by lvl asc, lvlpos asc
option (maxrecursion 16);
Změny: Doplnil jsem v předchozím příkladě zbytečně vynechaný kód, odkomentoval jsem řazení. Je to prakticky ve stavu, jako to dříve fungovalo. Ale nemám možnost to ověřit.
Asi vím, co Tě teď brzdí, hierarchický návrh tabulky. Sice to je snadné, ale asi se mi to nepodaří zopakovat.
Ještě tu jsem s návrhem (diagramem) hierarchii podporující tabulkou, podobnou, jako těžím dotazem.
Kdysi dávno jsem zplodil toto: TreeView ve WEBFORMS ASP.NET a hierarchická data v jedné tabulce ,
je to sice vbnet, ale přepsat to je otázka minut.
Ok... co takhle… viz. obrázek. Rekurzi na úrovni SQL nedělej, udělej ji až při vykreslení.
Model menu
public class MenuModel
{
public int ID { get; set; }
public int Nadrazeny_ID { get; set; }
public string Nazev { get; set; }
}
Hlavní stránka
@model int
@{Layout = ""; }
@{
ViewData["Title"] = "Home Page";
var menuItems = ViewData["MenuItems"] as List<MenuModel>;
}
<div class="dropdown-menu">
<ul>
@foreach (var hlavni in menuItems.Where(x => x.Nadrazeny_ID == Model))
{
<li>
@hlavni.Nazev
@{ await Html.RenderPartialAsync("PodPolozkaMenu", hlavni.ID, ViewData); }
</li>
}
</ul>
</div>
Partial stránka pro rekurzi
@model int
@{
var menuItems = ViewData["MenuItems"] as List<MenuModel>;
var aktualniUrovne = menuItems.Where(x=>x.Nadrazeny_ID == Model).ToList();
}
@if (aktualniUrovne.Count > 0)
{
<ul>
@foreach (var uroven in menuItems.Where(x => x.Nadrazeny_ID == Model))
{
<li>
@uroven.Nazev
@{await Html.RenderPartialAsync("PodPolozkaMenu", uroven.ID, ViewData);}
</li>
}
</ul>
}
Super tak nakonec jsem to nějak překopal a funguje díky moc. 
Ahoj, díky za uznání a trpělivost. Jsem rád, že Ti to pomohlo. 
Zobrazeno 18 zpráv z 18.