类别 - 带有 dapper 和 SQL 服务器的子类别列表

Category - subcategory listing with dapper and SQL Server

我有一个要求,其中有两个实体:CategoryBookmark。一个类别可以包含一些子类别 and/or 一些书签。我的table结构如下图:

tbl类别

ID int PK,
Name nvarchar

tbl书签

ID int PK
Name nvarchar

tblBookmarkCategories

CategoryID int (foreignKey)
BookmarkID int (foreignKey)

同样我的实体如下:

public class CategoryTree
{
    public int ID { get; set; }
    public string Name { get; set; }
    public ICollection<CategoryTree> SubCategory { get; set; }
    public ICollection<Bookmark> Bookmarks { get; set; }
}

public class Bookmark
{
    public int ID { get; set; }
    public string Name { get; set; }
}

如何使用 dapper 显示类别列表及其子类别和书签?我想以以下格式显示结果:

Category 1
   Bookmark 1
   Category 1.1
       Bookmark 1.1
       Bookmark 1.2
   Category 1.2
Category 2
   Bookmark 2
   Category 2.1
       Category 2.1.1
   Category 2.2

由于Category和Subcategory也有关系,你可以在“tblCategories”中增加一个“ParentID”列table,使用它,你可以根据“ParentID”列找到子类别,像这样:

Dapper是用来从数据库中查询数据的,我比较喜欢一次加载所有的分类和书签,然后根据分类查找子分类和书签。

因此,我创建了以下 类:

public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int ParentID { get; set; }

    public virtual ICollection<Category> SubCategories { get; set; }
    public virtual ICollection<Bookmark> Bookmarks { get; set; }
}

public class Bookmark {
    public int ID { get; set; }
    public string Name { get; set; }
    public int CategoryID { get; set; }
}

对于get/display类别及其子类别,我们可以使用递归的方法检查当前类别是否包含子类别,如果包含子类别,则从类别列表中过滤数据。详细代码如下:

    public class HomeController : Controller
    { 
        private readonly IConfiguration _configuration; 
        public HomeController(IConfiguration configuration)
        { 
            _configuration = configuration;
        } 
        //Index page, display the categories and bookmarks
        public IActionResult DapperIndex()
        {
            //get the connection string
            var connectionstring = _configuration.GetConnectionString("DefaultConnection");

            //get all categories and bookmarks
            List<Category> allcategories = new List<Category>();
            using (SqlConnection connection = new SqlConnection(connectionstring))
            {
                allcategories = connection.Query<Category>("SELECT * FROM tblCategories").ToList(); 

            }
            List<Bookmark> allbookmarks = new List<Bookmark>();
            using (SqlConnection connection = new SqlConnection(connectionstring))
            {
                allbookmarks = connection.Query<Bookmark>("select b.Id, b.Name, bc.CategoryID from tblBookmarks as b join tblBookmarkCategories as bc on b.id = bc.BookmarkID").ToList();

            }
            List<Category> categories = allcategories
                .Where(e => e.ParentID == 0) /* grab only the root parent nodes */
                .Select(e => new Category
                {
                    ID = e.ID,
                    Name = e.Name,
                    ParentID = e.ParentID,
                    SubCategories = GetSubCategory(allcategories,allbookmarks, e.ID), /* Recursively grab the children */
                    Bookmarks = GetBookmarks(allbookmarks, e.ID)
                }).ToList();

            ViewBag.categoriesList = categories;
            return View();
        }
        //get the subcategories
        private static List<Category> GetSubCategory(List<Category> items, List<Bookmark> bookmarks, int parentId)
        {
            return items.Where(x => x.ParentID == parentId)
                .Select(e => new Category
                {
                    ID = e.ID,
                    Name = e.Name,
                    ParentID = e.ParentID,
                    SubCategories = GetSubCategory(items,bookmarks, e.ID),
                    Bookmarks = GetBookmarks(bookmarks,e.ID) 
                }).ToList();
        }
        //get the bookmarks.
        public static List<Bookmark> GetBookmarks(List<Bookmark> bookmarks, int categoryid)
        {
            return bookmarks.Where(c => c.CategoryID == categoryid).Select(e=> new Bookmark()
            {
                ID= e.ID,
                Name = e.Name,
                CategoryID = e.CategoryID
            }).ToList();
        } 
    }

.cshtml 页面中的代码:

    @{ 
        List<Category> categorylist = ViewBag.categoriesList as List<Category>;
        void ShowTree(List<Category> categories)
        {
            if (categories != null)
            {
                foreach (var item in categories)
                {
                    <li>
                        <span>@item.Name</span>
                        @*display the bookmarks*@
                        @if (item.Bookmarks.Any())
                        {
                            foreach (var mark in item.Bookmarks)
                            {

                                <ul> @mark.Name  </ul>
                            }
                        }
                        @*display the subcategories*@
                        @if (item.SubCategories.Any())
                        {
                            <ul>
                                @{ ShowTree(item.SubCategories.ToList());}
                            </ul>
                        }
                    </li>
                }
            }
        }
        ShowTree(categorylist);
    }

结果如下:

编辑:要在 Asp.net 核心应用程序中使用 Dapper,请通过 NuGet 安装“Dapper”,然后检查 Dapper Query Basics