NHibernateで嵌る

http://nhibernate.sourceforge.net/quickstart.htmlを参考にサンプルこさえても上手く行かず、2,3時間悩んだ。結局、NHibernateをデバッガで追ってようやく解決。

<?xml version="1.0" encoding="utf-8" ?> 

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" auto-import="false">

    <class name="User,User" table="users">
    <id name="Id" column="LogonId" type="String" length="20">
      <generator class="assigned" />
    </id>
    
    <property name="UserName" column="Name" type="String" length="40"/>
    <property name="Password" type="String" length="20"/>
    <property name="EmailAddress" type="String" length="40"/>
    <property name="LastLogon" type="DateTime"/>
  </class>
  
</hibernate-mapping>

マッピング対象となるクラスがグローバルな名前空間の場合、auto-import="false"をつけないと駄目っぽい。名前空間を含んだ完全なクラス名とクラス名の両方をコレクションに突っ込むところで、クラス名が重複してしまうのが原因です。これは、ライブラリで対処してほしいなぁ・・・

おまけ。MySql用のドライバーとしてByteFXDataDriverが付属していますが、ドキュメントを読む限りMySql4.0xまでっぽいので、Connector/Net版を自作。

using System;
using System.Data;
using System.Reflection;

namespace NHibernate.Driver {
  public class MySqlClientDriver : DriverBase {
    private System.Type connectionType;
    private System.Type commandType;

    public MySqlClientDriver() {
      connectionType = System.Type.GetType("MySql.Data.MySqlClient.MySqlConnection, MySql.Data");
      commandType = System.Type.GetType("MySql.Data.MySqlClient.MySqlCommand, MySql.Data");
    }

    public override System.Type CommandType {
      get  { return commandType; }
    }

    public override System.Type ConnectionType {
      get  { return connectionType; }
    }

    public override bool UseNamedPrefixInSql {
      get {return true;}
    }

    public override bool UseNamedPrefixInParameter {
      get {return true;}
    }

    public override string NamedPrefix {
      get {return "?";}
    }

    public override bool SupportsMultipleOpenReaders {
      get { return false;  }
    }

    public override bool SupportsPreparingCommands {
      get { return false; }
    }
  }
}

こいつを、MySqlDriver.dllとかにコンパイルして、

<add 
  key="hibernate.connection.driver_class"          
  value="NHibernate.Driver.MySqlClientDriver,MySqlDriver" 
/>

と、指定すればOK。

(追記)
SupportsPreparingCommandsはfalseを返す必要があるので修正しました。