かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

[LINQ to SQL]関連のあるデータを1回のクエリでとりたいんだよ

過去のLINQ to SQLに関して書いた時には気づかなかったことがあった!
http://d.hatena.ne.jp/okazuki/20070422/1177212508
http://d.hatena.ne.jp/okazuki/20070423/1177339579
http://d.hatena.ne.jp/okazuki/20070423/1177339578
http://blogs.wankuma.com/kazuki/archive/2007/08/16/90606.aspx
http://blogs.wankuma.com/kazuki/archive/2007/08/16/90607.aspx

とりあえずおさらいとして、下のような感じに定義したテーブルがあるとする。

create table Departments (
  ID int IDENTITY(1,1) primary key,
  Name nvarchar(100) not null,
  Version timestamp not null);
create table Employees(
  ID int IDENTITY(1,1) primary key,
  Name nvarchar(100) not null,
  Salary int not null,
  DeptID int not null,
  Version timestamp not null,
  constraint FK_EMP_DEPT
    foreign key(DeptID) references Departments(ID));
データは↓の表にあるようなのを入れておいた。(Versionカラムは省略)
Departments
ID Name
1 総務部
2 人事部
3 経理部
Employees
ID Name Salary DeptID
2 太郎 200000 1
5 二郎 250000 2
6 三郎 300000 3

LINQ to SQLクラスをプロジェクトに追加して、テーブルをぽとっと落とす。
ファイル名はEdu.dbmlにしといた。

image

これに対して、以下のようなプログラムを書いたとする。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LinqToSqlSample.Properties;

namespace LinqToSqlSample
{
    class Program
    {
        static void Main(string[] args)
        {
            EduDataContext ctx = new EduDataContext(
                Settings.Default.EmpMngConnectionString);
            ctx.Log = Console.Out;  // SQLを標準出力に吐くよ

            var emps = from emp in ctx.Employees
                       select emp;
            foreach (var emp in emps)
            {
                Console.WriteLine("{0}さん {1}部", emp.Name, emp.Departments.Name);
            }
        }
    }
}

これを実行すると下のようにSQL文がやたらいっぱい出てしまう。
これが非常に嫌だった。

SELECT [t0].[ID], [t0].[Name], [t0].[Salary], [t0].[DeptID], [t0].[Version]
FROM [dbo].[Employees] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

SELECT [t0].[ID], [t0].[Name], [t0].[Version]
FROM [dbo].[Departments] AS [t0]
WHERE [t0].[ID] = @p0
-- @p0: Input Int32 (Size = 0; Prec = 0; Scale = 0) [1]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

太郎さん 総務部部
SELECT [t0].[ID], [t0].[Name], [t0].[Version]
FROM [dbo].[Departments] AS [t0]
WHERE [t0].[ID] = @p0
-- @p0: Input Int32 (Size = 0; Prec = 0; Scale = 0) [2]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

二郎さん 人事部部
SELECT [t0].[ID], [t0].[Name], [t0].[Version]
FROM [dbo].[Departments] AS [t0]
WHERE [t0].[ID] = @p0
-- @p0: Input Int32 (Size = 0; Prec = 0; Scale = 0) [3]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

三郎さん 経理部部

これくらいいっぱつでちゃちゃっととってきてほしくて、ちょっと頑張った形跡が過去のエントリの中にあったりする。
結局できなかったけど。
でも、最近やっとやりかたがわかった!!!DataShapeというクラスを使えば解決らしい。
これを読んだら書いてあった。
使い方も簡単。インスタンスを作って、LoadWithを呼べばいいと書いてある。
早速実験!!!さっきのコードに赤字の部分を付け足して見た。

…DataShapeっていうクラス自体が見当たらない!?何でだろう?と考えてそれっぽいクラスを探して見たらあった。
DataOptionsという風に名前が変わってたっぽい。さすがBeta。気を取り直して赤字の部分を付け足して実行してみた。

プログラム
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LinqToSqlSample.Properties;
using System.Data.Linq;

namespace LinqToSqlSample
{
    class Program
    {
        static void Main(string[] args)
        {
            EduDataContext ctx = new EduDataContext(
                Settings.Default.EmpMngConnectionString);
            ctx.Log = Console.Out;

            // Employesと一緒にDepartmentsも読み込んでね
            DataLoadOptions ops = new DataLoadOptions();
            ops.LoadWith<Employees>(e => e.Departments);
            ctx.LoadOptions = ops;

            var emps = from emp in ctx.Employees
                       select emp;
            foreach (var emp in emps)
            {
                Console.WriteLine("{0}さん {1}部", emp.Name, emp.Departments.Name);
            }
        }
    }
}

実行結果
SELECT [t0].[ID], [t0].[Name], [t0].[Salary], [t0].[DeptID], [t0].[Version], [t1].[ID] AS [ID2], [t1].[Name] AS [Name2], [t1].[Version] AS [Version2]
FROM [dbo].[Employees] AS [t0]
INNER JOIN [dbo].[Departments] AS [t1] ON [t1].[ID] = [t0].[DeptID]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1

太郎さん 総務部部
二郎さん 人事部部
三郎さん 経理部部

おおおお!ちゃんと1回のクエリでとってきてる!!
こうやって指定するのかぁ。メモメモ。

投稿日時 : 2007年11月17日 0:12

Feedback

# re: [LINQ to SQL]関連のあるデータを1回のクエリでとりたいんだよ 2007/11/19 0:16 かるあ

このあたりのクエリ効率化に関しては
開発思考実験日記のこのエントリに詳しく書かれていましたよ~
http://d.hatena.ne.jp/dotnetmemo/20070809/1186670286

# re: [LINQ to SQL]関連のあるデータを1回のクエリでとりたいんだよ 2007/11/19 17:40 Streetw☆

LINQ to SQLって今まで何度か目にしてたんですが、「これ」のところのリンク先を読みながら初めて使ってみました。
とっても感動しました(TーT)(TーT)
今まで書いてたコードとLINQ to SQLを使ったコードの比較を行って、思わずニカニカしてしまいましたw
私、ウィザードとか好きじゃないけど、LINQ to SQLって自分で全部簡単に書くことができるんですね。
LINQ to SQL関連のエントリ、またお願いします!

# re: [LINQ to SQL]関連のあるデータを1回のクエリでとりたいんだよ 2007/11/19 21:50 かずき

>かるあさん
要チェックですね!!
一通り目を通しました!ありがとうございます。

>Streetw☆さん
私は手で書いてもウィザードで書いても同じような事になるならウィザード派ですw
まだまだ知らないところだらけだと思うので、多分書きます!
コメントありがとうございました

# [LINQ to SQL]動的に検索条件を組み立てたいよ 2007/11/20 23:18 かずきのBlog

[LINQ to SQL]動的に検索条件を組み立てたいよ

# burberry bags 2012/10/28 13:28 http://www.burberryoutletonlineshopping.com/burber

You have brought up a very great points , thanks for the post.
burberry bags http://www.burberryoutletonlineshopping.com/burberry-tote-bags.html

# burberry scarf 2012/10/28 13:28 http://www.burberryoutletonlineshopping.com/burber

Just wanna state that this is very useful , Thanks for taking your time to write this.
burberry scarf http://www.burberryoutletonlineshopping.com/burberry-scarf.html

# burberry mens shirts 2012/10/28 13:29 http://www.burberryoutletonlineshopping.com/burber

I enjoy the efforts you have put in this, regards for all the great articles.
burberry mens shirts http://www.burberryoutletonlineshopping.com/burberry-men-shirts.html

# wallet 2012/10/28 13:29 http://www.burberryoutletonlineshopping.com/burber

You are my aspiration, I own few blogs and very sporadically run out from brand :). "Analyzing humor is like dissecting a frog. Few people are interested and the frog dies of it." by E. B. White.
wallet http://www.burberryoutletonlineshopping.com/burberry-wallets-2012.html

# QborvMycHE 2014/07/18 2:05 http://crorkz.com/

FnHJQa Im thankful for the article.Really looking forward to read more.

# xgcQoCDwUkLHQa 2014/08/02 2:22 http://crorkz.com/

9NjF5e Im grateful for the blog article. Awesome.

タイトル
名前
Url
コメント