ASP.NET MVC获取多级类别组合下的产品

本篇是针对我在做项目过程中遇到的特定需求而做的一个Demo, 没有很大的通用性,读者酌情可绕行。

标题不能完全表达本意,确切的情景需要展开说。假设有三级分类,关于分类这样设计:

    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int ParentId { get; set; }
    }

然后产品可以属于多个分类,以下的Categories属性值是以英文逗号隔开、由分类编号拼接而成的字符串。

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Categories { get; set; }
    }

由于种种原因,Categories属性值只是存储了由第三级分类编号拼接而成的字符串。

在前端,需要把分类作为查询条件来查询产品,可能只选择一级分类,把一个数字字符串(比如"1")发送给服务端;可能同时选择一级和二级分类,也把一个数字字符串(比如"1,2")发送给服务端;当然,也有可能同时选择一级、二级和三级分类作为查询条件(比如"1,2,3")。换句话说,如果诸如"1"或"1,2"或"1,2,3"这样的查询条件转换成数组后,如果数组的每一个元素都被包含在Product的Categories属性值转换成的数组中,那这个产品就符合搜索条件。

简单来说,是这样:假设搜索条件是"1,2",Product的Categories属性值为"1,3,2,5",我们不是判断"1,2"这个字符串是否包含在"1,3,2,5"字符串中,而是把"1,2"先split成数组,叫做array1, 把"1,3,2,5"也split成数组,叫做array2,最后判断array1的每个元素是否都被包含在array2中。

还有一个问题需要解决:当前的Product的Categories属性值只存储了所有第三级分类编号拼接成的字符串,而前端输入的搜索条件可能会包含一级分类或二级分类等,所以,我们需要把Product转换一下,希望有一个类的某个属性值能存储由一级、二级、三级分类拼接而成的字符串。

    public class ProductWithThreeCate
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string AllCategoreis { get; set; }
    }

以上, AllCategoreis属性值就用来存储由一级、二级、三级分类拼接而成的字符串。

有一个方法获取所有分类:

        static List<Category> GetCategories()
        {
            return new List<Category>()
            {
                new Category(){Id = 1, Name = "根", ParentId = -1},
                new Category(){Id = 2, Name = "一级分类1",ParentId = 1},
                new Category(){Id = 3, Name = "一级分类2", ParentId = 1},
                new Category(){Id = 4, Name = "二级分类11",ParentId = 2},
                new Category(){Id = 5, Name = "二级分类12",ParentId = 2},
                new Category(){Id = 6, Name = "二级分类21",ParentId = 3},
                new Category(){Id = 7, Name = "二级分类22",ParentId = 3},
                new Category(){Id = 8, Name = "三级分类111",ParentId = 4},
                new Category(){Id = 9, Name = "三级分类112",ParentId = 4},
                new Category(){Id = 10, Name = "三级分类121",ParentId = 5},
                new Category(){Id = 11, Name = "三级分类122",ParentId = 5},
                new Category(){Id = 12, Name = "三级分类211",ParentId = 6},
                new Category(){Id = 13, Name = "三级分类212",ParentId = 6},
                new Category(){Id = 14, Name = "三级分类221",ParentId = 7}
            };
        }

有一个方法获取所有产品:

        static List<Product> GetProducts()
        {
            return new List<Product>()
            {
                new Product(){Id = 1, Name = "产品1",Categories = "10,12"},
                new Product(){Id = 2, Name = "产品2", Categories = "12,13"},
                new Product(){Id = 3, Name = "产品3",Categories = "10,11,12"},
                new Product(){Id = 4, Name = "产品4",Categories = "13,14"},
                new Product(){Id = 5, Name = "产品5",Categories = "11,13,14"}
            };
        }

接下来的方法是根据搜索条件(比如是"1,2")来查找满足条件的ProductWithThreeCate集合,如下:

        /// <summary>
        /// 获取满足某些条件的集合
        /// </summary>
        /// <param name="query">以英文逗号隔开的字符串,比如:2,5</param>
        /// <returns></returns>
        static List<ProductWithThreeCate> GetResultByQuery(string query)
        {
            //最终结果
            List<ProductWithThreeCate> result = new List<ProductWithThreeCate>();
            //临时结果 此时ProductWithThreeCat的属性AllCategoreis包含所有一级、二级、三级分类ID拼接成的字符串
            List<ProductWithThreeCate> tempResult = new List<ProductWithThreeCate>();
            //获取所有的产品
            List<Product> allProducts = GetProducts();
            //遍历这些产品
            foreach (var item in allProducts)
            {
                ProductWithThreeCate productWithThreeCate = new ProductWithThreeCate();
                productWithThreeCate.Id = item.Id;
                productWithThreeCate.Name = item.Name;
                //所有一级、二级、三级拼接成以英文逗号隔开的字符串
                string temp = string.Empty;
                //当前产品只包含三级拼接成的、也是以英文隔开的字符串,split成数组
                string[] theThirdCates = item.Categories.Split(',');
                //遍历这些三级数组
                foreach (string i in theThirdCates)
                {
                    //三级类别转换成整型
                    int theThirdInt = int.Parse(i);
                    //获取三级类别
                    Category theThirdCate = GetCategories().Where(c => c.Id == theThirdInt).FirstOrDefault();
                    //获取二级类别
                    Category theSecondCate = GetCategories().Where(c => c.Id == theThirdCate.ParentId).FirstOrDefault();
                    //获取一级类别
                    Category theFirstCate = GetCategories().Where(c => c.Id == theSecondCate.ParentId).FirstOrDefault();
                    temp += i + "," + theSecondCate.Id.ToString() + "," + theFirstCate.Id.ToString() + ",";
                }
                //去掉最后一个英文逗号
                temp = temp.Substring(0, temp.Length - 1);
                //转换成集合,去除重复项,比如不同的三级可能有相同的一级或二级父类
                IEnumerable<string> tempArray = temp.Split(',').AsEnumerable().Distinct();
                //所有一级、二级、三级拼接成以英文逗号隔开的字符串,但已经去除了重复的一级和二级
                string tempagain = string.Empty;
                //再次遍历集合拼接成字符串
                foreach (var s in tempArray)
                {
                    tempagain += s + ",";
                }
                productWithThreeCate.AllCategoreis = tempagain.Substring(0, tempagain.Length - 1);
                tempResult.Add(productWithThreeCate);
            }
            //遍历临时结果
            foreach (var item in tempResult)
            {
                //把当前包含一级、二级、三级的,以英文逗号隔开的字符串split成数组
                string[] itemArray = item.AllCategoreis.Split(',');
                //把当前查询字符串split成数组
                string[] queryArray = query.Split(',');
                //如果queryArray的每一个元素都被包含在itemArray中,那就保存起来
                if (queryArray.All(x => itemArray.Contains(x)) == true)
                {
                    result.Add(item);
                }
            }
            return result;
        }                

客户端的调用如下:

            List<ProductWithThreeCate> result = GetResultByQuery("2,5");
            //遍历最终的结果
            foreach (var item in result)
            {
                Console.WriteLine(item.Name+ "  " + item.AllCategoreis);
            }
            Console.ReadKey(); 

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • ASP.NET MVC实现单个图片上传、限制图片格式与大小并在服务端裁剪图片

    本篇,在ASP.NET MVC4下实现单个图片上传,具体功能包括: 1.在客户端选择图片,并限制图片的大小和格式 2.在客户端上传图片,并显示预览图 3.在服务端限制图片的大小和格式 4.在服务端保存图片时,把图片裁剪成某个固定尺寸 本篇源码在:https://github.com/darrenji/FileUploadInMVC 实现的大致思路是: 客户端限制图片大小和格式,通过写一个jQuery插件来实现 服务端实现图片裁剪,通过使用ImageSize组件来实现 首先是一个用来承载上传信息的

  • ASP.NET MVC实现登录后跳转到原界面

    有这样的一个需求:提交表单,如果用户没有登录,就跳转到登录页,登录后,跳转到原先表单提交这个页面,而且需要保持提交表单界面的数据. 提交表单的页面是一个强类型视图页,如果不考虑需要保持提交表单界面的数据,可以先设计这样的一个Model: public class Student { public string Name{get;set;} public string ReturnUrl{get;set;} } 在提交表单的视图页,大致这么写: @using (Html.BeginForm("In

  • ASP.NET MVC使用JSAjaxFileUploader插件实现单文件上传

    先看效果: 上传文件显示进度条: 停止上传按钮和关闭缩略图按钮: 限制上传文件的类型: 限制上传文件的尺寸: 上传成功后显示缩略图.文件名以及回传信息: 点击界面上的删除按钮,界面删除,同步删除文件夹中文件. 重新上传文件,界面删除,同步删除文件夹中文件,并界面显示新的缩略图.文件名等. HomeController 由于需要把保存到文件夹文件的路径.文件名等回传给界面,所以需要一个类,专门负责回传给客户端所需要的信息. public class UploadFileResult { publi

  • ASP.NET MVC实现区域或城市选择

    每次在"万达影城"网上购票总会用到左上角选择城市的功能.如下: 今天就在ASP.NET MVC中实现一下.我想最好的方式应该是写一个插件,但自己在这方面的功力尚欠缺,如果大家在这方面有好的解决方案,希望在这一起交流,那将会更好. 大致思路如下: 点击"更换"弹出div,用bootstrap来实现 div中的tabs,用jqueryui来实现 tab项中的城市,用jquery.tmpl.min.js模版来实现 有关城市的Model: public class City

  • ASP.NET MVC解决上传图片脏数据的方法

    在"在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片"中,已经实现了在客户端和服务端限制图片大小和格式,以及在服务端裁剪图片.但还有一个重要的话题是需要面对的,那就是图片脏数据问题. 假设用户添加产品信息,并且上传了图片,可之后用户没有点击页面上的添加按钮,这就导致上传图片成为"脏数据",存在着却一直不会被使用.解决这个问题的大致思路是: 在上传图片的时候,把图片保存到一个临时文件夹,或者叫缓存文件夹 当用户真正保存

  • ASP.NET MVC使用正则表达式验证手机号码

    在ASP.NET MVC中,可以使用RegularExpression特性来验证手机号码. public class Customer { [Required(ErrorMessage = "必填")] [Display(Name = "手机号")] [RegularExpression(@"^1[3458][0-9]{9}$", ErrorMessage = "手机号格式不正确")] public string PhoneN

  • ASP.NET MVC实现城市或车型三级联动

    三级或多级联动的场景经常会碰到,比如省.市.区,比如品牌.车系.车型,比如类别的多级联动......我们首先想到的是用三个select来展示,这是最通常的做法.但在另外一些场景中,比如确定搜索条件的时候,对于三级联动来说,可能选择1个,2个,或3个条件,我想,以下的方式可能更适合: 以上,可以只选择品牌,或同时选择品牌.车系,或同时选择品牌.车系.车型,最后把选择的内容展示到input上,并以逗号隔开. 可以实现的功能包括: 点击最上面的input弹出div,此时只显示品牌区域 点击最左边拼音首

  • ASP.NET MVC使用Boostrap实现产品展示、查询、排序、分页

    在产品展示中,通常涉及产品的展示方式.查询.排序.分页,本篇就在ASP.NET MVC下,使用Boostrap来实现. 源码放在了GitHub: https://github.com/darrenji/ProductsSearchSortPage 先上效果图: 最上面是搜索和排序,每次点击搜索条件.排序,或者删除搜索条件都会触发异步加载. 中间部分为产品展示,提供了列表和格子这2种显示方式. 最下方为分页. 能实现的功能包括: 点击某一个搜索条件,该搜索条件被选中,选中项以标签的形式显示到"搜索

  • ASP.NET MVC使用typeahead.js实现输入智能提示功能

    使用typeahead.js可以实现预先输入,即智能提示,本篇在ASP.NET MVC下实现.实现效果如下: 首先是有关城市的模型. public class City { public int Id { get; set; } public string Name { get; set; } public string PinYin { get; set; } } 在HomeController中响应前端请求返回有关City的json数据. public ActionResult GetCit

  • ASP.NET MVC使用jQuery的Load方法加载静态页面及注意事项

    使用使用jQuery的Load方法可以加载静态页面,本篇就在ASP.NET MVC下实现. Model先行: public class Article { public int Id { get; set; } public string Url { get; set; } } 在HomeController中的Index方法,向视图传递一个Article强类型. public class HomeController : Controller { public ActionResult Ind

随机推荐