国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

LINQ學習筆記(1)

2019-11-14 16:31:24
字體:
來源:轉載
供稿:網友

學習資源參考 : http://m.survivalescaperooms.com/lifepoem/archive/2011/12/16/2288017.html

 

常用方法是 Where, OrderBy, Select 

高級點的是 GroupBy, Join

 

LINQ 主要用于解決早期多種數據類型之間的交互關系,還有forloop的場景,比如以前我們總覺得 List<Class> 不就是table 嘛,干嘛要搞分類強轉,不能學一下js嗎。過后我們就自己用泛類,反射和委托等等實現了一些方便處理不同數據格式的問題(基本上有點像js了)。后來微軟就統一大家的方式,寫出了完整的LINQ啦,LINQ后來的發展很好,還用來做LINQ TO SQL 在不需要寫SQL 語句下也能做好 CRUD 操作,現在是在 entity framework 下。

 

雖然如此強大,不過這里只是記入一些入門篇而已。而且本文只作為個人復習而已,如果在下理解有誤請高手給予糾正。新手嘛請遠離,以免我誤人子弟,哈哈.

思想: 我覺得實現原理依然是用了反射,委托,泛類,調用的邏輯基本上和js差不多, 就是封裝了forloop,然后讓你傳一個function進來操作每個row進行修改過濾等等。只是語法用解析器調整了一下,變得容易看容易寫。

 

下面是一些基本的使用和解釋,都是用代碼呈現。

where 的重點就是內部是一個表達式,結果要是 true || false , true就保留,false就被過濾掉(解析時會運用到每一行上)
select 的用途是可以對結果在進行一次修改, 還可以返回新的對象 (解析是會運用到每一行上)
where和select()內n是一個參數,寫m也行,這個參數代表了List里面的值,如果List里面是對象,那就是對象咯

上代碼

   List<string> nameList = new List<string> { "keatkeat", "xinyao", "ahyou" };            //我想過濾數據,保留字母長度 = 5 的,然后我希望把字便大寫             //方法語法                      IEnumerable<string> result1 = nameList                                        .Where(n => n.Length == 5)                                         .Select(n => n.ToUpper());            //查詢語法            var result = from name in nameList                         where name.Length == 5                         select name.ToUpper();                                                         string json = stoogesV3.toJson(result); //["AHYOU"]

站在js的角度可以這樣去理解

  function List(array) {            this.array = array;            this.whereList = [];            this.selectFn;        };        List.PRototype.where = function (fn) {            this.whereList.push(fn); //把所有where語句加進去            return this;        };        List.prototype.select = function (fn) {            this.selectFn = fn; //只會有一個select語句            return this;        };        List.prototype.toList = function () {            var result = []; //這里偷懶,只返回普通數組            var array = this.array;                        for (var i = array.length - 1; i >= 0 ; i--) {                var value = array[i];                            var is_remove = this.whereList.some(function (fn) {                    return (fn(value) === false); //只要一個false就remove                     });                if (is_remove) {                    array.splice(i, 1);                }                else {                    var finalValue = (this.selectFn) ? this.selectFn(value) : value; //用selectFn 修改最終的值                    result.unshift(finalValue);                }            }            return result;        };        var nameList = new List(["keatkeat", "xinyao", "ahyou"]);        var result = nameList.where(function (n) {            return n.length === 5;        }).select(function (n) {            return n.toUpperCase();        }).toList();        alert(result);

 

OrderBy 

            //用thenBy來連接            List<Person> list = new List<Person> {                 new Person{ name= "keatkeat", age= 18 },                new Person{ name= "xinyao", age= 19 },                new Person{ name= "ahyou", age= 17 },                new Person{ name= "bhyou2", age= 17 },                new Person{ name= "chyou2", age= 17 }             };            var result = list.OrderBy(n => n.age).ThenByDescending(n => n.name);                     var result1 = from person in list                          orderby person.age, person.name descending                          select person;            string json = stoogesV3.toJson(result1);

 

子查詢 

注意,LINQ to Object 的子查詢會在每次調用result的時候執行,所以優化的方法是提前把依賴的值裝在變量,而不要一直運行子查詢。

        string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };        //最好的做法其實是先拿出來         int shorter = names.Min(n => n.Length);        var result = names.Where(n => n.Length == shorter);        // 獲取所有長度最短的名字(注意:可能有多個)        var result1 = names.Where(n => n.Length == (names.Min(g => g.Length)));        var result2 = from n in names                     where n.Length == (from n2 in names orderby n2.Length select n2.Length).First()                     select n;

 

LINQ 是后運行的,也就是說一般上當我們寫好語句,在還沒有調用result時(比如 toJson | foreach ), 他是不會執行的,一直等到我們調用才運行,當然凡事總有另外 !

下面就是一些會讓語句直接執行的情況 

 

            int[] numbers = { 10, 9, 8, 7, 6 };            int firstNumber = numbers.First();// 10            int lastNumber = numbers.Last();// 6            ClassA obj = array.FirstOrDefault(); //如果沒有是null, int 是 0,base on 類型的default value            int secondNumber = numbers.ElementAt(1);// 9            int count = numbers.Count();// 5            int min = numbers.Min(); // 6            int max = numbers.Max();//10            bool hasTheNumberNine = numbers.Contains(9); //true            bool hasElements = numbers.Any();// true            bool hasAnOddElement = numbers.Any(n => (n % 2) == 1);//true 只要其中一個比配到的 

 

 

concat vs union 

concat 就是把2個List combine 

union 也是combine 但是,union 會自動distict,過濾掉重復的數據, 它是combine之后一起全部distict哦. 

 

            int[] num1 = { 1, 2, 2, 3 };            int[] num2 = { 3, 4, 5 };            IEnumerable<int> concat = num1.Concat(num2);//[1,2,2,3,3,4,5]            IEnumerable<int> union = num1.Union(num2);//[1,2,3,4,5]

 

ToList 

剛說LINQ是后執行,為了優化可以用 ToList() 把result裝起來 , 但是記得他依然是引用不是clone哦

        List<user> user_list = new List<user> { new user { name = "xinyao", age = 5 }, new user { name = "keatkeat", age = 10 } };        List<user> result = user_list.Where(n => n.name == "xinyao").ToList<user>(); //這里保存的是引用

 

常用的 filter 過濾器

        //skip 和 take 可以當場MySQL 的 limit 5,50 就好象 skip 5 take 50        string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };        var result = names.Take(3); //那前3個        var result1 = names.Skip(3); //skip 頭3個         var result2 = names.TakeWhile(n => n.Length > 2); //從條件之后才開始拿         var result3 = names.SkipWhile(n => n.Length > 2); //頭開始 skip 直到條件之后拿        var reuslt4 = names.Distinct(); //過濾掉多余重復的

 

尋找差異值

Except , 找出 enum1有而enum2沒有的值集合,這里頭的比較是使用引用==,也就是說如果指針不同就算值一樣也算false不一樣。

        List<string> a = new List<string> { "a", "b" };        List<string> b = new List<string> { "a" };        var result = a.Except(b); //這里用的是引用== ,也就是說不通指針值一樣也算不一樣  可以找出 a有而b沒有的值        

 

接下來就是重頭戲 GroupBy, Join 了

我們常因為SQL索引難以優化的情況下,利用多次select來取出table, 然后就可以利用join或者groupBy來代替sql的工作了。

 

GroupBy 思想

運行GroupBy查詢之后,返回的是一個group集合, 想想看開始是一個table,你把row group起來后, 它就像是變成了多個table, 每個table分到了一部分的row 

所以在foreach result 的時候它每一條記入都是一個類似table的集合里面包含了group好的row .

GroupBy 變化較多,重點是明白思想 

             List<Product> products = new List<Product> {                new Product {code = "mk100",color = "red",size = "m"},               new Product {code = "mk100",color = "red",size = "s"},               new Product {code = "mk100",color = "yellow",size = "s"},               new Product {code = "mk100",color = "yellow",size = "m"},               new Product {code = "mk100",color = "yellow",size = "l"},               new Product {code = "mk200",color = "red",size = "s"},               new Product {code = "mk200",color = "red",size = "m"},            };                       var result = products                        .GroupBy(n => new { n.code, n.color })                        .Select(n => new { code = n.First().code, color = n.First().color, size = String.Join(",", n.Select(m => m.size)) });
          //select 的時候不要重復的column可以直接獲取第一個row的值就行了
string json = stoogesV3.toJson(result);

 

Join 稍微復雜一些

join其實比較適合寫 "語句" 而不是一般的 "方法" 
語句看上去會好看很多

join 就是inner join 

要實現left join 可以只用一些巧妙方法

隨便談談說join, 在1對多的情況,將會生產跟多的row,1的會被復制更多出來,有點笛卡爾積的feel 

如果是inner join ,匹配不到的row就被刪除了, left join 是對 a table 進行完全保留,即使它某些row沒有和 b table 匹配上.

看代碼吧

            var result = from a in enum1                         join b in enum2 on a.name equals b.name //equals 就是等于 =                         where a["name"].ToString() == "xinyao" //這里可以加condition                         orderby a["name"].ToString()                         select new { name = a["name"].ToString(), like = b["name"] }; //to obj                                   var result1 = enum1.Join(                     enum2, //join table b                     a => a.name, //on a                      b => b.name, //on b                      (a, b) => new { name = a["name"], like = b["name"] } //final result                 ).Where(n => n.name == "xinyao").OrderBy(n => n.name); //后來才加

是不是差很多,下面的能看嗎...

left join : 

into 關鍵字還可以有其它變化,這里只是其中一種使用它的方法。

            var result1 = from a in enum1                          join b in enum2 on a["name"] equals b["name"]                          into x  //這里的 x 就好比是 a 一樣,a 是 enum1里的row不是table哦                           //select x; 請不要直接 select x, 因為這里的 x 已經因為innerjoin 而把不match的row刪除了,                           select new { name = a["name"], row = x }; //我們新創建一個對象來收藏每個row, 這里如果x被刪除的話,它應該是一個空值                        foreach (var zz in result1)             {                foreach (var yy in zz.row)                 {                    //沒有匹配到 on 條件的話,zz.row是空的,也就不會進來這里了                }            }

 

好啦,還有很多留給下一篇吧

先記入在這里,下次才搬.

javascript 里的 reduce 

reduce 有點循環對一個值做處理的概念,

定義一個初始值(它會一直跟著循環,然后我們可以對它做修改,loop完后返回這個值),可以叫他流動值

loop array時 每一次loop可以獲取當前array的內容和獲取這個流動值,每次loop的返回值是下一個loop的流動值,這就是它可以循環改造的原理了。

代碼上 

這是Javascript版 

        var array = [{ number: 1 }, { number: 2 }, { number: 3 }];        var sum = array.reduce(function (total, obj, i, array) {            return total += obj.number;        }, 0);        //原始值是0 , 流動值是total , obj 就是 loop array 當前的 對象啦。

這是c#版

    public class Obj    {        public Int64 number { get; set; }    }        List<Obj> array = new List<Obj> { new Obj { number = 1 }, new Obj { number = 2 }, new Obj { number = 2 } };        Int64 sum = array.Aggregate(0, delegate(Int64 total, Obj obj)        {            return total += obj.number;        });
  Int32 sum2 = array.Aggregate(0, (total, obj) => total += obj.number);
//簡短版本,這樣比較不容易指定類型,如果邏輯簡單的話可以寫這個,否則直接用委托吧。

   Aggregate 第一個參數,delegate第一參數,delegate返回值還有 sum 的類型一定一樣,delegate 第2參數就是array內容的類型

 


上一篇:委托delegate,繼承

下一篇:[C#]獲取MAC地址

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 敦化市| 通江县| 鹤峰县| 普兰县| 扶风县| 南涧| 安顺市| 灵宝市| 勐海县| 仪陇县| 阿拉善盟| 边坝县| 和顺县| 阿图什市| 武义县| 绵竹市| 新泰市| 巧家县| 昌邑市| 昂仁县| 兴业县| 宜兴市| 个旧市| 峨边| 张掖市| 延寿县| 江阴市| 怀宁县| 德阳市| 原阳县| 隆昌县| 仁怀市| 贵州省| 资兴市| 望城县| 鄂尔多斯市| 开远市| 东乡族自治县| 普兰县| 达拉特旗| 海盐县|