Nhibernate-data-types-mapping
NHibernate-データ型マッピング
この章では、マッピングデータ型について説明します。 エンティティのマッピングは簡単で、エンティティクラスは常に <class>、<subclass>、および<joined-subclass> マッピング要素を使用してデータベーステーブルにマッピングされます。 値型にはさらに何かが必要です。マッピング型が必要な場所です。
NHibernateは、さまざまなデータタイプをマップできます。 以下は、サポートされている最も一般的なデータ型のリストです。
Mapping type | .NET type | System.Data.DbType |
---|---|---|
Int16 | System.Int16 | DbType.Int16 |
Int32 | System.Int32 | DbType.Int32 |
Int64 | System.Int64 | DbType.Int64 |
Single | System.Single | DbType.Single |
Double | System.Double | DbType.Double |
Decimal | System.Decimal | DbType.Decimal |
String | System.String | DbType.String |
AnsiString | System.String | DbType.AnsiString |
Byte | System.Byte | DbType.Byte |
Char | System.Char | DbType.StringFixedLength—one character |
AnsiChar | System.Char | DbType.AnsiStringFixedLength—one character |
Boolean | System.Boolean | DbType.Boolean |
Guid | System.Guid | DbType.Guid |
PersistentEnum | System.Enum(an enumeration) | DbType for the underlying value |
TrueFalse | System.Boolean | DbType.AnsiStringFixedLength—either 'T' or 'F' |
YesNo | System.Boolean | DbType.AnsiStringFixedLength—either 'Y' or 'N' |
DateTime | DateTime | DbType.DateTime—ignores milliseconds |
Ticks | System.DateTime | DbType.Int64 |
TimeSpan | System.TimeSpan | DbType.Int64 |
Timestamp | System.DateTime | DbType.DateTime—as specific as the database supports |
Binary | System.Byte[] | DbType.Binary |
BinaryBlob | System.Byte[] | DbType.Binary |
StringClob | System.String | DbType.String |
Serializable | Any System.Object marked with SerializableAttribute | DbType.Binary |
CultureInfo | System.Globalization.CultureInfo | DbType.String—five characters for culture |
Type | System.Type | DbType.String holding the Assembly Qualified Name |
上記の表は、下記のポインターを詳細に説明しています。
- 単純な数値型から文字列まで、すべて varchars、chars などを使用してさまざまな方法でマッピングできます。 文字列blob、およびデータベースがサポートするすべてのさまざまなタイプ。
- また、ゼロと1を使用するフィールド、true、false、またはTとFを含む文字フィールドの両方に*ブール値*をマップすることもできます。
- データベース内のバックエンド、ブール値にマップする方法を定義するさまざまな方法があります。
- タイムゾーンオフセット、夏時間などを含めて、 DateTime のマッピングを処理できます。
- *列挙*をマップすることもできます。これらを文字列または基になる数値にマップできます。
データベースとStudentクラスの両方で同じプロパティ名を使用する簡単な例を見てみましょう。
では、学生クラスでFirstMidNameをFirstNameに変更します。FirstMidName列は変更しませんが、NHibernateにこの変換を実行することを知らせる方法を確認します。 以下は、更新された学生クラスです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NHibernateDemoApp {
class Student {
public virtual int ID { get; set; }
public virtual string LastName { get; set; }
public virtual string FirstName { get; set; }
}
}
NHibernateマッピングファイルの実装を次に示します。
<?xml version = "1.0" encoding = "utf-8" ?>
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemoApp"
namespace = "NHibernateDemoApp">
<class name = "Student">
<id name = "ID">
<generator class = "native"/>
</id>
<property name = "LastName"/>
<property name = "FirstName" column = "FirstMidName" type = "String"/>
</class>
</hibernate-mapping>
この例では、FirstNameフィールドが.NET文字列で、FirstMidName列が SQL nvarchar であると想定しています。 NHibernateにこの変換の実行方法を伝えるには、名前を FirstName に、列を FirstMidName に設定し、この特定の変換に適したマッピングタイプをStringに指定します。
以下は Program.cs ファイルの実装です。
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using System;
using System.Linq;
using System.Reflection;
namespace NHibernateDemoApp {
class Program {
static void Main(string[] args) {
NHibernateProfiler.Initialize();
var cfg = new Configuration();
String Data Source = asia13797\\sqlexpress;
String Initial Catalog = NHibernateDemoDB;
String Integrated Security = True;
String Connect Timeout = 15;
String Encrypt = False;
String TrustServerCertificate = False;
String ApplicationIntent = ReadWrite;
String MultiSubnetFailover = False;
cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source +
Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
TrustServerCertificate + ApplicationIntent + MultiSubnetFailover";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
x.LogSqlInConsole = true;
});
cfg.AddAssembly(Assembly.GetExecutingAssembly());
var sefact = cfg.BuildSessionFactory();
using (var session = sefact.OpenSession()) {
using (var tx = session.BeginTransaction()) {
var students = session.CreateCriteria<Student>().List<Student>();
Console.WriteLine("\nFetch the complete list again\n");
foreach (var student in students) {
Console.WriteLine("{0} \t{1} \t{2}", student.ID, student.FirstName,
student.LastName);
}
tx.Commit();
}
Console.ReadLine();
}
}
}
}
これで、アプリケーションを実行すると、次の出力が表示されます。
NHibernate: SELECT this_.ID as ID0_0_, this_.LastName as LastName0_0_,
this_.FirstMidName as FirstMid3_0_0_ FROM Student this_
Fetch the complete list again
3 Allan Bommer
4 Jerry Lewis
ご覧のとおり、異なるプロパティ名がデータベースの列名にマッピングされています。
*enum* タイプのStudentクラスに別のプロパティを追加する別の例を見てみましょう。 これがStudentクラスの実装です。
using System;
using System.Collections.Generic;
using System.Linq; using System.Text;
using System.Threading.Tasks;
namespace NHibernateDemoApp {
class Student {
public virtual int ID { get; set; }
public virtual string LastName { get; set; }
public virtual string FirstName { get; set; }
public virtual StudentAcademicStanding AcademicStanding { get; set; }
}
public enum StudentAcademicStanding {
Excellent,
Good,
Fair,
Poor,
Terrible
}
}
ご覧のとおり、列挙には、Excellent、Good、Fair、Poor、Terribleなどのさまざまな値が含まれている可能性があります。
マッピングファイルにジャンプすると、これらの各プロパティが、新しく追加された AcademicStanding プロパティを含むマッピングファイルにリストされていることがわかります。
<?xml version = "1.0" encoding = "utf-8" ?>
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2"
assembly = "NHibernateDemoApp" namespace = "NHibernateDemoApp">
<class name = "Student">
<id name = "ID">
<generator class = "native"/>
</id>
<property name = "LastName"/>
<property name = "FirstName" column = "FirstMidName" type = "String"/>
<property name = "AcademicStanding"/>
</class>
</hibernate-mapping>
データベースも変更する必要があるため、SQL Serverオブジェクトエクスプローラーに移動し、データベースを右クリックして[新しいクエリ]オプションを選択します。
クエリエディターを開き、次のクエリを指定します。
DROP TABLE [dbo].[Student]
CREATE TABLE [dbo].[Student] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[LastName] NVARCHAR (MAX) NULL,
[FirstMidName] NVARCHAR (MAX) NULL,
[AcademicStanding] NCHAR(10) NULL,
CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC)
);
このクエリは、最初に既存の学生テーブルを削除してから、新しいテーブルを作成します。
上記のように、実行アイコンをクリックします。 クエリが正常に実行されると、メッセージが表示されます。
データベースとテーブルのドロップダウンを展開し、Studentテーブルを右クリックして、View Designerを選択します。
これで、新しく作成されたテーブルが表示されます。これには、新しいプロパティAcademicStandingもあります。
次の Program.cs ファイルに示すように、2つのレコードを追加しましょう。
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using System;
using System.Linq;
using System.Reflection;
namespace NHibernateDemoApp {
class Program {
static void Main(string[] args) {
NHibernateProfiler.Initialize();
var cfg = new Configuration();
String Data Source = asia13797\\sqlexpress;
String Initial Catalog = NHibernateDemoDB;
String Integrated Security = True;
String Connect Timeout = 15;
String Encrypt = False;
String TrustServerCertificate = False;
String ApplicationIntent = ReadWrite;
String MultiSubnetFailover = False;
cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source +
Initial Catalog + Integrated Security + Connect Timeout + Encrypt +
TrustServerCertificate + ApplicationIntent + MultiSubnetFailover";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
});
cfg.AddAssembly(Assembly.GetExecutingAssembly());
var sefact = cfg.BuildSessionFactory();
using (var session = sefact.OpenSession()) {
using (var tx = session.BeginTransaction()) {
var student1 = new Student {
ID = 1,
FirstName = "Allan",
LastName = "Bommer",
AcademicStanding = StudentAcademicStanding.Excellent
};
var student2 = new Student {
ID = 2,
FirstName = "Jerry",
LastName = "Lewis",
AcademicStanding = StudentAcademicStanding.Good
};
session.Save(student1);
session.Save(student2);
var students = session.CreateCriteria<Student>().List<Student>();
Console.WriteLine("\nFetch the complete list again\n");
foreach (var student in students) {
Console.WriteLine("{0} \t{1} \t{2} \t{3}", student.ID,
student.FirstName, student.LastName, student.AcademicStanding);
}
tx.Commit();
}
Console.ReadLine();
}
}
}
}
アプリケーションを実行してみましょう。コンソールウィンドウに次の出力が表示されます。
Fetch the complete list again
1 Allan Bommer Excellent
2 Jerry Lewis Good
では、Student Tableを右クリックして、データベースを見てみましょう。
[データの表示]を選択すると、次のスクリーンショットに示すように、学生テーブルに2つのレコードが表示されます。
2つのレコードが追加され、アランにはAcademicStanding 0があり、ジェリーにはAcademicStanding 1があることがわかります。 これは、.Netでは最初の列挙値のデフォルトが0であるためです。これは、 StudentAcademicStanding を見ると優れています。 一方、Student.csファイルではGoodが2番目であるため、値は1です。