简体   繁体   中英

Category - subcategory listing with dapper and SQL Server

I have a requirement where there are two entities: Category and Bookmark . A category can contain some subcategories and/or some bookmarks. My table structure is as shown below:

tblCategories

ID int PK,
Name nvarchar

tblBookmarks

ID int PK
Name nvarchar

tblBookmarkCategories

CategoryID int (foreignKey)
BookmarkID int (foreignKey)

Similarly my entities are as following:

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; }
}

How can I show the category list along with their subcategories and bookmarks using dapper? I want to display the result in the following format:

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

Since the Category and Subcategory also contain relationship, you could add a "ParentID" column in the "tblCategories" table, by using it, you could find the subcategory based on the "ParentID" column, like this:

在此处输入图片说明

The Dapper is used to query data from the database, I prefer to load all the categories and the bookmarks at once, then based on the category to find the subcategories and bookmarks.

So, I create the following classes:

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; }
}

To get/display the category and its subcategory, we could use the recursive method to check whether current category contains subcategory, if it contains the subcategory, filter the data from the category list. The detail code as below:

    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();
        } 
    }

Code in the .cshtml page:

    @{ 
        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);
    }

The result as below:

在此处输入图片说明

Edit: To use Dapper in Asp.net Core application, install "Dapper" via NuGet, then check the Dapper Query Basics .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM