はじめてのS2Dao.NETその3

複数テーブルをリンクする場合ですが、

ビューのような仮想的なDTOを作成して自由にマッピングさせるという方法もあります。その場合はSQLの自動生成は使えませんが・・

id:sugimotokazuyaさんに教えて頂いたので、早速実験です。
まずは、仮想的なDTOを作成します。

[Table("Grandchild")]
public class GrandchildDto {
    private int id;
    private string name;
    private int cid;
    private string cname;
    private int pid;
    private string pname;

    public int ID {
        get { return id; }
        set { id = value; }
    }

    public string Name {
        get { return name; }
        set { name = value; }
    }

    public int CID
    {
        get { return cid; }
        set { cid = value; }
    }

    public string CName
    {
        get { return cname; }
        set { cname = value; }
    }
    public int PID
    {
        get { return pid; }
        set { pid = value; }
    }

    public string PName
    {
        get { return pname; }
        set { pname = value; }
    }

    public override string ToString () {
        return String.Format ("{0}:{1}", ID, Name);
    }
}

親、子、孫テーブルの要素を全て集めたDTOにしています。次に、これらを取得するSQLは自動生成出来ないので、自分で指定することになります。Java版ではSQLファイルを作成しますが、.NETではSQLファイルをリソースとして埋め込む必要があります。また、SQLファイルにはネーミングルールがあって、DAOインタフェースの完全名_メソッド名.sqlとしなければなりません。例えば、

using System;
using System.Collections;
using Seasar.Dao.Attrs;

namespace HelloDao3
{
    [Bean(typeof(GrandchildDto))]
    public interface IGrandchildDtoDao
    {
        IList GetAllList();

        [Query("id=/*id*/")]
        Grandchild GetGrandchildDtoByID(int id);
    }

}

このインタフェースのGetAllListメソッドに対するSQLファイルだと、

IGrandchildDtoDao_GetAllList.sql

という名前でファイルを作成して埋め込みます。実際にメソッドに対するSQLを読み込むときはインタフェース名_メソッド名で埋め込みリソースを探します。

ちなみにSQLファイルはこんな感じ。

select g.id, g.name, c.id as cid, c.name as cname, p.id as pid, p.name as pname 
from grandchild g, child c, parent p where g.cid = c.id and c.pid = p.id

ところで、Visual Studioを使用している場合、落とし穴があります。SQLファイルを埋め込む時に、リソース名にデフォルトの名前空間がついてしまいます。例えば、今回の場合だと、HelloDao3.IGrandchildDtoDao_GetAllList.sql(HelloDao3がデフォルトの名前空間)となってしまいます。もし、インタフェースIGrandchildDtoDaoが異なる名前空間に属していたら、埋め込みファイルを見つけることが出来ません。なので、Visual Studioで作業する場合は、基本的にインタフェースをデフォルトの名前空間に所属させる必要があります。


デフォルトの名前空間は結構嵌るので出来れば無効にしたいんですが、未入力に出来ないんですよね・・・