• Linq学习之路(07) 使用Linq进行参数化编程step by step


    我们在程序中往往需要添加过滤器的功能,检索数据的时候希望按照某些条件进行筛选或者排序,解决方案有很多种,比如拼SQL语句或者进行参数化编程。拼过滤条件是最低级最不安全的一种解决方案,不能很好的表现出面向对象编程的思想,正好本人最近在研究Linq,那么今天本人就使用Linq进行参数化编程,数据源还是参考我前面写的那些文章。

    给大家看一下UI:

     

      

    这里我们希望根据Title检索关键字,PageCount主要是想过滤掉那些不满足条件的Objects,SortOrder主要就是指定按照什么条件进行排序,有升序也有降序。

    主要界面就是这样,好吧,下面我们就开始如何一步一步实现这些功能:

    step1:初始换窗体

      这里我主要讲一下PageCount这个下拉框的初始化,我们设置下拉列表中每个项的显示的名字和与其对应的值,为了让界面变得友好,用户一眼就看出来是什么意思,所以我这里用了KeyValuePair来保存Key/Value,Key是给用户看的,而Value是给我们程序员看的,我们根据Value进行相应的操作。附上代码:

     cmbCountFilter.DisplayMember = "Key";
     cmbCountFilter.ValueMember = "Value";
     cmbCountFilter.DataSource = new KeyValuePair<String, int?>[] 
     {
         new KeyValuePair<String, int?>("any", null),
         new KeyValuePair<String, int?>("at least 100", 100),
         new KeyValuePair<String, int?>("at least 200", 200),
         new KeyValuePair<String, int?>("at least 300", 300)
     };

    另外,我们还要简单的讲一下用于显示检索结果的控件DataGridView控件,由于我们想让他显示我们自定义的元素,所以我们需要将DataGridView控件的AutoGenerateColumns属性值设置为false,这样我们就能让该控件显示我们自定义的列了,给你也给出代码:

           //这里我们只想显示自定义的三列:Title,Publisher,PageCount,
                //所以我们要把AutoGenerateColumns属性设为false
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.Columns.Clear();
                dataGridView1.Columns.Add(
                    new DataGridViewTextBoxColumn() { DataPropertyName = "Title", HeaderText = "Title" });
                dataGridView1.Columns.Add(
                    new DataGridViewTextBoxColumn() { DataPropertyName = "PageCount", HeaderText = "Pages" });
                dataGridView1.Columns.Add(
                    new DataGridViewTextBoxColumn() { DataPropertyName = "Publisher", HeaderText = "Publisher" });

    初始化工作我们就做的差不多了,下面开始我们的第二步:

    step2:自定义条件检索QueryByCondition

      大多数情况下,检索的条件会很多,如果每个条件都写一个方法,那么会大大的增加我们的代码量,而且方法重用的可能性不大,为了构建重用度非常好的方法,这里我们使用参数化编程,提高方法的重用度,代码量也惊人的变少,也是面向对象编程的初衷。

            /// <summary>
            /// 自定义条件检索
            /// </summary>
            /// <typeparam name="TSortKey">排序规则</typeparam>
            /// <param name="minPageCount">最小页码</param>
            /// <param name="titleFilter">标题过滤条件</param>
            /// <param name="sortSelector">排序条件</param>
            /// <param name="ascending">是否升序</param>
            public IEnumerable<Book> QueryByCondition<TSortKey>(int? minPageCount, string titleFilter, Func<Book, TSortKey> sortSelector, Boolean ascending)
            {
                IEnumerable<Book> books;
    
                books = SampleData.Books;
                if (minPageCount.HasValue)
                {
                    books = books.Where(book => book.PageCount >= minPageCount);
                }
                if (!String.IsNullOrEmpty(titleFilter))
                {
                    books = books.Where(book => book.Title.Contains(titleFilter));
                }
                if (sortSelector != null)
                {
                    if (ascending)
                    {
                        books = books.OrderBy(sortSelector);
                    }
                    else
                    {
                        books = books.OrderByDescending(sortSelector);
                    }
                }
    
                return books;
            }

    上面这段代码就是我们这个demo里面最核心的代码,我们根据传进来的这些参数进行判断检索,得到我们想要的那些数据。

    step3:根据我们在UI界面选择的条件检索我们期望的数据:

            /// <summary>
            /// 数据绑定
            /// </summary>
            public IEnumerable<Book> LoadData()
            {
                IEnumerable<Book> books = null;
    
                int? minPageCount;
                string titleFilter;
    
                minPageCount = (int?)cmbCountFilter.SelectedValue;
                titleFilter = txtTitleFilter.Text;
    
                switch (cmbSortOrder.SelectedIndex)
                {
                    case 0:
                        books =
                            QueryByCondition(minPageCount, titleFilter, book => book.Title, true);
                        break;
                    case 1:
                        books =
                            QueryByCondition(minPageCount, titleFilter, book => book.Title, false);
                        break;
                    case 2:
                        books =
                            QueryByCondition(minPageCount, titleFilter, book => book.Publisher.Name, true);
                        break;
                    case 3:
                        books =
                            QueryByCondition(minPageCount, titleFilter, book => book.Publisher.Name, false);
                        break;
                    case 4:
                        books =
                            QueryByCondition(minPageCount, titleFilter, book => book.PageCount, true);
                        break;
                    case 5:
                        books =
                            QueryByCondition(minPageCount, titleFilter, book => book.PageCount, false);
                        break;
                    default:
                        books =
                            QueryByCondition<Object>(minPageCount, titleFilter, null, true);
                        break;
                }
    
                //这里将检索到的books转换为List列表非常重要
                //因为Linq中对数据的检索存在Derfferd Query
                //如果这里没有加上ToList()方法的话,在UI层我们是不会得到结果的
                return books.ToList();
            }

    这段代码主要是根据我们选择的过滤条件和排序规则进行判断,然后传入相应的参数调用QueryByCondition方法。

    step4:最后一步,在btn_click事件中调用我们的LoadData方法:

            /// <summary>
            /// 按钮点击事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnSearch_Click(object sender, EventArgs e)
            {
                dataGridView1.DataSource = LoadData();
            }

    好了大功告成了,我们来看看我们的成果:

    1、按关键字检索:

      

    2、按最小页码检索:

      

    3、按排序规则检索:

      

    4、组合查询:

      

    5、默认查询:

      

    ok,这篇文章就讲到这里,let's make oop develop better!!!

    姓名:王卯东 英文名:Michael QQ:942352461 Email:armdong@163.com 主要研究方向:javascript,require.js;
  • 相关阅读:
    HDU-5980
    HDU-5974
    HDU-5979
    关于position的定位
    javascript学习笔记w3chool
    表单相关css技巧
    fis压缩工具的使用
    将HTML页面内容存入json数组
    中介PHP连接前台HTML与数据库MySQL
    lesscss的使用
  • 原文地址:https://www.cnblogs.com/ARMdong/p/linqparameterizedfunc.html
Copyright © 2020-2023  润新知