IEnumerableとIQueryable

ExcelをC#から扱う方法をご紹介しましたが、データ処理をする際にLINQが使えたらと思うのは私だけじゃないはず。以下のテストデータに対してクエリする方法を見ておきます。

 TestData.cs

namespace LinqToEtcetra
{
    using System;

    public class TestData
    {
        public int No { get; set; }
        public string Name { get; set; }
        public DateTime TestDate { get; set; }
        public int Score { get; set; }
    }
}

 

1.Linq To Csv

データ整理にExcelを使う場合、CSVファイルに対してLinqクエリ発行できればと思う時に使えるライブラリがこちら。早速使ってみます。まずNugetで

>PM install-package linqtocsv

としてパッケージをインストールしておきます。テストコードはこちら。

 LinqToCsvTest.cs

namespace LinqToEtcetra
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using LINQtoCSV;

    public class LinqToCsvTest
    {
        private readonly CsvContext csvContext = new CsvContext();
        private readonly CsvFileDescription fileDescription = new CsvFileDescription()
        {
            SeparatorChar = ',',
            FirstLineHasColumnNames = true,
            TextEncoding = Encoding.GetEncoding("Shift-JIS")
        };

        public void WriteFile()
        {
            var testData =  new List<TestData>(){
                new TestData(){No=1, Name="hiro",TestDate=new DateTime(2014,7,14),Score=70},
                new TestData(){No=2, Name="yuki",TestDate=new DateTime(2014,7,14),Score=85},
                new TestData(){No=3, Name="mayu",TestDate=new DateTime(2014,7,14),Score=100},
                new TestData(){No=4, Name="taku",TestDate=new DateTime(2014,7,14),Score=90},
            };
            csvContext.Write<TestData>(testData, "test.csv", fileDescription);
        }

        public void ReadFile()
        {
            var testDataSequence = csvContext.Read<TestData>("test.csv");
            // ご自由にLinqください。
            string maxScorePerson = testDataSequence.OrderByDescending(i => i.Score).First().Name;
            Console.WriteLine("最高得点は" + maxScorePerson + "さんです.");
        }
    }
}

これでもイイのですが、CSVファイルのレイアウトが変わる場合はデータ構造定義しておくことが推奨されているようです。

 TestData.cs(修正)

namespace LinqToEtcetra
{
    using System;
    using LINQtoCSV;

    public class TestData
    {
        [CsvColumn(FieldIndex=1)]
        public int No { get; set; }

        [CsvColumn(FieldIndex = 2)]
        public string Name { get; set; }

        [CsvColumn(FieldIndex = 3, OutputFormat="yyyy/MM/dd hh:mm:ss")]
        public DateTime TestDate { get; set; }

        [CsvColumn(FieldIndex = 4)]
        public int Score { get; set; }
    }
}

書きだされ、読みだされるCSVファイルはこちら。

csv_test

 

2.Linq To Excel

同じデータがExcelファイルとして用意されていたとしましょう。こちらの場合はNugetから

>PM install-package linqtoexcel

としておきます。Linq To Excelの使い方はこちら。

LinqToExcelTest.cs

namespace LinqToEtcetra
{
    using System;
    using System.Linq;
    using LinqToExcel;

    public class LinqToExcelTest
    {
        public void WriteFile()
        {
            throw new NotImplementedException("LinqToExcelではファイル出力はサポートされていません.");
        }

        public void ReadFile()
        {
            ExcelQueryFactory excel = new ExcelQueryFactory("test.xlsx");
            // ご自由にLinqください
            string maxScorePerson = excel.Worksheet("Sheet1").OrderByDescending(i => i["Score"]).First()["Name"];
            Console.WriteLine("最高得点は" + maxScorePerson + "さんです.");
        }
    }
}

想定するExcelファイルは以下です。

test_excel

LinqtoCsvの場合ファイル書き込みがサポートされていましたが、LinqToExcelの場合はサポートされていませんのPIAを使うか、NPOIを使って対応くださいませ。

 

3.IEnumerable と IQueryable

ネット上のいろんな方が記載されているので何も新しくないのですが、IEnumerableとIQueryableの違いはクエリがどこで行われるかです。

IEnumerablevsIQueryable

クエリ結果は同じ。ちなみに先の例で、LinqToCsvはIEnumerableですが、LinqToExcelはIQueryableです。IQueryableのほうが式木作成して外部で適切なフィルタ処理が必要な分、クエリは高速化が見込まれますが作るのが大変です。LinqToCsvとLinqToExcelで差はあるのかは・・・皆様ご自身でご確認ください。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中