LinQ查詢基礎(三)LINQ to ADO.net(1)LINQ to DataSet實現複雜資料查詢

何畢之發表於2018-05-05
先說明一下這篇文章需要用到的DataSet
        /// <summary>
        /// 建立一個有一張(姓名,年齡,性別)3個欄位表格的DataSet
        /// </summary>
        /// <returns></returns>
        public static DataSet GetDataSet()
        {
            string[] nameSet = { "張三", "李四", "王五", "趙六", "李翠花", "吳霞", "周八", "李秀蘭", "李雲龍" };
            string[] genderSet = { "男", "男", "女", "男", "女", "女", "男", "女", "男" };
            int[] ageSet = { 18, 20, 21, 22, 19, 20, 18, 26, 24 };

            DataSet ds = new DataSet("PeopleDs");
            DataTable dt = new DataTable("PeopleDt");

            ds.Tables.Add(dt);

            dt.Columns.AddRange(new DataColumn[]
            {
                new DataColumn("name",Type.GetType("System.String")),
                new DataColumn("gender",Type.GetType("System.String")),
                new DataColumn("age",Type.GetType("System.Int32"))
            });

            for (int i = 0; i < nameSet.Length; i++)
            {
                DataRow row = dt.NewRow();
                row["name"] = nameSet[i];
                row["gender"] = genderSet[i];
                row["age"] = ageSet[i];
                dt.Rows.Add(row);
            }

            return ds;
        }

        /// <summary>
        /// 建立一個有一張(姓名,年齡,性別,成績表好)4個欄位表格和一張(成績編號,數學成績,語文成績,英語成績)4個欄位的表的DataSet
        /// </summary>
        /// <returns></returns>
        public static DataSet BulidDataSet()
        {
            string[] nameSet = { "張三", "李四", "王五", "趙六", "李翠花", "吳霞", "周八", "李秀蘭", "李雲龍" };
            string[] genderSet = { "男", "男", "女", "男", "女", "女", "男", "女", "男" };
            int[] ageSet = { 18, 20, 21, 22, 19, 20, 18, 26, 24 };
            int[] math = { 70, 80, 90, 50, 86, 78, 76, 65 };
            int[] chinese = { 80, 85, 86, 75, 81, 74, 77, 95 };
            int[] english = { 77, 76, 80, 55, 62, 66, 74, 85 };

            DataSet ds = new DataSet("Students");
            DataTable dt = new DataTable("StuDt");
            ds.Tables.Add(dt);
            DataTable dts = new DataTable("ScoDt");
            ds.Tables.Add(dts);

            dt.Columns.AddRange(new DataColumn[]
            {
                new DataColumn("name",Type.GetType("System.String")),
                new DataColumn("gender",Type.GetType("System.String")),
                new DataColumn("age",Type.GetType("System.Int32")),
                new DataColumn("id",Type.GetType("System.Int32"))
            });

            for (int i = 0; i < nameSet.Length; i++)
            {
                DataRow row = dt.NewRow();
                row["name"] = nameSet[i];
                row["gender"] = genderSet[i];
                row["age"] = ageSet[i];
                row["id"] = i + 1;
                dt.Rows.Add(row);
            }

            dts.Columns.AddRange(new DataColumn[]
            {
                new DataColumn("id",Type.GetType("System.Int32")),
                new DataColumn("math",Type.GetType("System.Int32")),
                new DataColumn("chinese",Type.GetType("System.Int32")),
                new DataColumn("english",Type.GetType("System.Int32"))
            });

            for (int i = 0; i < math.Length; i++)
            {
                DataRow row = dts.NewRow();
                row["id"] = i + 1;
                row["math"] = math[i];
                row["chinese"] = chinese[i];
                row["english"] = english[i];
                dts.Rows.Add(row);
            }

            return ds;
        }

3.1.1 使用LINQ toDataSet

    LINQ to DataSet 可以簡單理解成通過LINQDataSet中儲存的資料進行查詢。通常包含以下步驟:

1)獲取DataSet/DataTable資料來源

2)將DataTable轉換成IEnumerable<T>型別

3)使用LINQ語法編寫程式

4)使用查詢結果

由於DataSet本身是DataTable的集合,包含多個DataTable和它們之間的關係,所以LINQ to DataSet實際是對DataTable進行資料查詢。

 

3.1.2 查詢單個資料表

在對DataTable進行資料查詢時,必須使用DataTable類的AsEnumberable()方法。

            #region 單表查詢

            DataSet ds = GetDataSet();
            DataTable dt = ds.Tables["PeopleDt"];

            //查詢dt中的所有記錄 演示AsEnumerable()和Field<T>()的使用
            var query =
                from v in dt.AsEnumerable()
                select v;
            Console.WriteLine("Query1:");
            foreach (var v in query)
            {
                Console.WriteLine("姓名:{0}, 性別:{1}, 年齡:{2}", v.Field<string>("name"), v.Field<string>("gender"), v.Field<int>("age"));
            }
            //條件查詢
            var query1 =
                from v in dt.AsEnumerable()
                orderby v.Field<int>("age") descending
                where v.Field<int>("age") > 20
                where (int)v["age"] < 25
                select v.Field<string>("name");
            Console.WriteLine("Query2:");
            foreach (var v in query1)
                Console.Write(v + "    ");

            #endregion
查詢結果:

3.1.3查詢多個表 

查詢的方法有很多種,在解決問題時應該儘可能尋找更多方法,從而得到最簡單有效並且適用的那種方法。

            #region 多表查詢
            DataSet StuDS = BulidDataSet();
            DataTable StuDt = StuDS.Tables["StuDt"];
            DataTable ScoDt = StuDS.Tables["ScoDt"];

            //查詢所有有成績的學生資訊
            var query =
                from stu in StuDt.AsEnumerable()
                from sco in ScoDt.AsEnumerable()
                where (int)stu["id"] == (int)sco["id"]
                select stu;

            Console.WriteLine("有成績的學生:");
            foreach (var v in query)
                Console.WriteLine("姓名:{0}, 性別:{1}, 年齡:{2}", (string)v["name"], v.Field<string>("gender"), (int)v["age"]);

            Console.WriteLine();

            //查詢所有沒有成績的學生
            var query2 = StuDt.AsEnumerable().Except(query);

            Console.WriteLine("沒有成績的學生:");
            foreach (var v in query2)
                Console.WriteLine("姓名:{0}, 性別:{1}, 年齡:{2}", (string)v["name"], v.Field<string>("gender"), (int)v["age"]);
            #endregion
查詢結果:

3.1.4用查詢資料建立資料表及修改表中欄位資料

LINQ to DataSet通過DataTableExtensions類提供的擴充套件方法CopyToDataTable()將查詢結果直接複製到一個新的資料表中,從而可以將查詢結果繫結到介面控制元件(DataGridView),也可以使用DataTable的一些特性。

            DataSet StuDS = BulidDataSet();
            DataTable StuDt = StuDS.Tables["StuDt"];
            DataTable ScoDt = StuDS.Tables["ScoDt"];

            //查詢所有有成績並且年齡大於20的學生資訊
            var query =
                from stu in StuDt.AsEnumerable()
                from sco in ScoDt.AsEnumerable()
                where (int)stu["id"] == (int)sco["id"]
                where (int)stu["age"] > 20
                select stu;

            //通過CopyToDataTable()方法建立新的副本
            DataTable newDt = query.CopyToDataTable<DataRow>();

            foreach (var v in newDt.AsEnumerable())
                Console.WriteLine("姓名:{0}, 性別:{1}, 年齡:{2}", v["name"], v["gender"], v["age"]);

            Console.WriteLine();
            //通過SetField()方法修改表中欄位資料
            foreach (var v in newDt.AsEnumerable())
            {
                int age = v.Field<int>("age");
                v.SetField<int>("age", age + 2);
            }

            foreach (var v in newDt.AsEnumerable())
                Console.WriteLine("姓名:{0}, 性別:{1}, 年齡:{2}", v["name"], v["gender"], v["age"]);
輸出結果:

3.1.5使用資料檢視DataView

            #region 資料檢視DataView
            DataSet ds = GetDataSet();
            DataTable dt = ds.Tables[0];

            //用DataTable的AsDataView()方法建立DataView
            DataView DV1 = dt.AsDataView();

            //用LINQ獲取特定條件的資訊的DataView
            EnumerableRowCollection<DataRow> query =
                from v in dt.AsEnumerable()
                where v.Field<string>("name").StartsWith("李")
                orderby (int)v["age"] descending
                select v;
            DataView DV2 = query.AsDataView();

            //DataView類的RowFilter和Sort屬性對資料進行過濾
            DataView dv = dt.AsDataView();
            //RowFilter屬性設定篩選條件 年齡大於20
            dv.RowFilter = "age > 20";
            //為RowFilter屬性賦值為null或String.Empty,清除過濾資訊,二選一
            dv.RowFilter = null;
            dv.RowFilter = string.Empty;
            //通過Sort對資訊排序
            dv.Sort = "age asc, name desc";
            //為Sort屬性賦值為null或String.Empty,清除過濾資訊,二選一
            dv.Sort = null;
            dv.Sort = string.Empty;
            #endregion

相關文章