Visual C# 2013 パーフェクトマスター 8章 LINQ

[Amazon.co.jp： VisualC#2013ﾊﾟｰﾌｪｸﾄﾏｽﾀｰ (Perfect Master SERIES): 金城 俊哉: 本](http://www.amazon.co.jp/VisualC-2013%EF%BE%8A%EF%BE%9F%EF%BD%B0%EF%BE%8C%EF%BD%AA%EF%BD%B8%EF%BE%84%EF%BE%8F%EF%BD%BD%EF%BE%80%EF%BD%B0-Perfect-Master-SERIES/dp/4798040193)

自分の不明点をとりまとめ。理解できているところは割愛。

# LINQによるデータの抽出
LINQとは.NET3.5以降で実装された様々なデータ集合に対して標準化された方法でデータへの問い合わせを行う手法。

## LINQの種類
* LINQ to ADO.NET
    * LINQ to SQL
    * LINQ to Entities
    * LINQ to DataSet
* LINQ to XML
* LINQ to Objects   
LINQ to Objectsは配列やコレクションを直接操作できる。   
以前はforeachを使って記述していたが、LINQを使えばシンプルで読みやすいコードが記述できる

## LINQとクエリ式
### 特定の範囲の数値を取り出す

```csharp
        static void Main(string[] args)
        {
            int[] numbers = { 1, 2, 3, 4, 5 };
            var query =
                from n in numbers
                where n >= 2 && n <= 4
                select n;
            foreach(var a in query)
            {
                Console.WriteLine(a);
            }

        }
```

### 文字列データを取り出す

```csharp
    class Program
    {
        static string [] getString(string[] str)
        {
            return (
                from s in str
                where s.StartsWith("h")
                select s).ToArray();
        }

        static void Main(string[] args)
        {
            string[] text = { "hogehoge", "fugafuga", "piyopiyo" };
            string[] resulit = getString(text);
            foreach(var n in resulit)
            {
                Console.WriteLine(n);
            }
        }
    }
```

## LINQを利用した並び替え

```csharp
        static void Main(string[] args)
        {
            int[] num = { 50, 200, 15, 3, 75, 100 };
            var r = from n in num
                    //where n >= 10
                    orderby n
                    select n;
            foreach(var n in r)
            {
                Console.WriteLine(n);
            }
        }
```

### メソッドを使った式に書き換えてみる

```csharp
    class Program
    {
        static void Main(string[] args)
        {
            int[] num = { 200, 300, 100, 500, 400 };
            //var r = from n in num
            //        where n >= 200 && n <= 400
            //        orderby n
            //        select n;
            // ラムダ式にしてみる
            var r = num.Where((n) => n >= 200 && n <= 400).OrderBy((n) => n);
            //((n) => n >= 200).Where((n)=> n <=400) と書く事もできる
            foreach(var s in r)
            {
                Console.WriteLine(s);
            }
        }
    }
```

# LINQによるデータの加工
## select句におけるデータの加工
select句では抽出したデータに対して処理を行うことができる

```csharp
        static void Main(string[] args)
        {
            int[] num = { 100, 200, 300, 400, 500 };
            var r = from n in num
                    select n * 1.05;
            foreach(var s in r)
            {
                Console.WriteLine(s);
            }
        }
```

### メソッドを使った式に書き換えてみる

```csharp
        static void Main(string[] args)
        {
            int[] num = { 100, 200, 300, 400, 500 };
            var r = num.Where((n)=> n >=200 & n <=400).Select(n => n * 1.05);
            foreach(var s in r)
            {
                Console.WriteLine(s);
            }

        }
```

## インスタンスのデータを加工する
select句ではnewキーワードによるオブジェクトの作成を行う事ができる。
これを利用してクラス型のように内部に複数のデータを持つオブジェクトを抽出し、新たにオブジェクトを作る事も可能。


```csharp
    class Item
    {
        public string code;
        public string name;
        public int price;
    }
    
    class Program
    {

        static void Main(string[] args)
        {
            Item[] i =
            {
                new Item() { code = "A110", name = "Apple", price = 200 },
                new Item() { code = "G201", name = "Orange", price = 150 },
                new Item() { code = "GR50", name = "Grape", price = 450}
            };

            //var q = from n in i select n;
            var q = i.Select(n=>n);
            foreach(var s in q)
            {
                Console.WriteLine("{0} {1} {2}",s.code,s.name,s.price);
            }
        }
    }
```

### 匿名オブジェクトを利用して新たなインスタンスを生成

```csharp
    class Item
    {
        public string code;
        public string name;
        public int price;
    }

    class Program
    {

        static void Main(string[] args)
        {
            Item[] i =
            {
                new Item() { code = "A110", name = "Apple", price = 200 },
                new Item() { code = "G201", name = "Orange", price = 150 },
                new Item() { code = "GR50", name = "Grape", price = 450}
            };

            //select new で新しいインスタンスとして生成している
            // var q = from n in i select new {Name = n.code, Price = n.price * 1.05};
            var q = i.Select((n)=> new {Name = n.code, Price = n.price * 1.05});

            foreach (var s in q)
            {
                Console.WriteLine("{0} {1}", s.Name, s.Price);
            }
        }
    }
```