📅  最后修改于: 2023-12-03 15:17:19.974000             🧑  作者: Mango
在 C# 中使用 LINQ 查询可以非常方便地从数据库中获取数据。在本文中,我们将介绍如何使用 LINQ 查询从同一个表中获取父子数据。
假设我们有这样一张表:
CREATE TABLE [dbo].[Category](
[CategoryId] [int] IDENTITY(1,1) NOT NULL,
[CategoryName] [nvarchar](50) NOT NULL,
[ParentCategoryId] [int] NULL,
CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED
(
[CategoryId] ASC
)
);
这个表表示一个分类,其中 ParentCategoryId
表示父分类的 CategoryId
。例如,我们有一个分类结构如下:
1-食品
2-水果
3-蔬菜
4-叶菜
5-根菜
在表中,对应数据应该是这样的:
CategoryId | CategoryName | ParentCategoryId
-----------|--------------|----------------
1 | 食品 | NULL
2 | 水果 | 1
3 | 蔬菜 | 1
4 | 叶菜 | 3
5 | 根菜 | 3
我们的目标是通过一次查询获取所有分类,包括每个分类的子分类。
首先我们需要创建数据模型,可以使用 Entity Framework 或者 Dapper 等 ORM 工具。这里我们使用 Entity Framework。
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public int? ParentCategoryId { get; set; }
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> ChildCategories { get; set; }
}
注意,我们在实体类中添加了 ParentCategory
和 ChildCategories
两个导航属性,用于表示父分类和子分类。这里使用了 Entity Framework 的延迟加载技术,使得在查询时可以自动获取父子分类的数据。
有了数据模型之后,我们就可以使用 LINQ 查询来获取数据了。首先我们需要获取根分类,即 ParentCategoryId
为 NULL 的分类。
var context = new DbContext();
var rootCategories = context.Categories
.Where(c => c.ParentCategoryId == null)
.ToList();
接着,我们可以递归获取每个分类的子分类。这里可以使用迭代或者递归两种方式,这里我们演示递归方式。
foreach (var category in rootCategories)
{
category.ChildCategories = GetChildCategories(category.CategoryId);
}
List<Category> GetChildCategories(int categoryId)
{
var childCategories = context.Categories
.Where(c => c.ParentCategoryId == categoryId)
.ToList();
foreach (var category in childCategories)
{
category.ChildCategories = GetChildCategories(category.CategoryId);
}
return childCategories;
}
递归方法 GetChildCategories
会根据传入的分类 ID 获取该分类的子分类,并将子分类分别递归获取子分类。最后返回子分类列表。
获取到数据之后,我们可以将数据输出到控制台或者 Web 页面上。这里我们使用 HTML 的无序列表(<ul>
和 <li>
标签)来表示分类,每个分类下面的子分类使用嵌套列表表示。
void RenderCategory(Category category)
{
Console.WriteLine("<li>");
Console.WriteLine(category.CategoryName);
if (category.ChildCategories.Count > 0)
{
Console.WriteLine("<ul>");
foreach (var childCategory in category.ChildCategories)
{
RenderCategory(childCategory);
}
Console.WriteLine("</ul>");
}
Console.WriteLine("</li>");
}
Console.WriteLine("<ul>");
foreach (var category in rootCategories)
{
RenderCategory(category);
}
Console.WriteLine("</ul>");
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public int? ParentCategoryId { get; set; }
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> ChildCategories { get; set; }
}
class Program
{
static void Main(string[] args)
{
var context = new DbContext();
var rootCategories = context.Categories
.Where(c => c.ParentCategoryId == null)
.ToList();
foreach (var category in rootCategories)
{
category.ChildCategories = GetChildCategories(category.CategoryId);
}
Console.WriteLine("<ul>");
foreach (var category in rootCategories)
{
RenderCategory(category);
}
Console.WriteLine("</ul>");
}
static List<Category> GetChildCategories(int categoryId)
{
var context = new DbContext();
var childCategories = context.Categories
.Where(c => c.ParentCategoryId == categoryId)
.ToList();
foreach (var category in childCategories)
{
category.ChildCategories = GetChildCategories(category.CategoryId);
}
return childCategories;
}
static void RenderCategory(Category category)
{
Console.WriteLine("<li>");
Console.WriteLine(category.CategoryName);
if (category.ChildCategories.Count > 0)
{
Console.WriteLine("<ul>");
foreach (var childCategory in category.ChildCategories)
{
RenderCategory(childCategory);
}
Console.WriteLine("</ul>");
}
Console.WriteLine("</li>");
}
}
使用 LINQ 查询从同一个表中获取父子数据并不难,只需要使用递归的方式获取每个分类的子分类即可。这里我们使用 Entity Framework 实现了数据模型,并使用 LINQ 查询获取数据。最后使用 HTML 的列表标签将数据输出到控制台。