Nhibernate-mapping-component

提供:Dev Guides
移動先:案内検索

NHibernate-マッピングコンポーネント

この章では、コンポーネントのマッピングについて説明します。 NHibernateでは、* componentは値オブジェクトです*。 独自のIDはありません。

  • この例としては、お金のオブジェクト、財布、または財布にお金が入っている場合がありますが、そのお金の正確な身元は無関係です。
  • 独自の主キーはありませんが、コンポーネント自体は所有オブジェクトと同じテーブルに永続的です。

学生が住所を持っている簡単な例を見てみましょう。住所は、それに関連付けられた* Locationクラス*のオブジェクトです。

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 virtual Location Address { get; set; }
   }

   public class Location {
      public virtual string Street { get; set; }
      public virtual string City { get; set; }
      public virtual string Province { get; set; }
      public virtual string Country { get; set; }
   }

   public enum StudentAcademicStanding {
      Excellent,
      Good,
      Fair,
      Poor,
      Terrible
   }
}

ここで、次のクエリを実行してデータベースを更新する必要もあります。最初にStudentテーブルを削除してから、Locationクラスの列も含む新しいテーブルを作成します。

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,
   [Street] NVARCHAR (100) NULL,
   [City] NVARCHAR (100) NULL,
   [Province] NVARCHAR (100) NULL,
   [Country] NVARCHAR (100) NULL,
   CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC)

);

次に、直接Studentクラスの一部ではない列をマップしますが、それらはLocationクラスのプロパティであり、Locationクラスオブジェクトはstudentクラスで定義されます。 正しくマップするためのコンポーネントが必要です。 次のコードに示すように、 student.hbm.xml ファイルにコンポーネントを作成しましょう。

<?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"/>

      <component name = "Address">
         <property name = "Street"/>
         <property name = "City"/>
         <property name = "Province"/>
         <property name = "Country"/>
      </component>

   </class>
</hibernate-mapping>

このコンポーネントはアドレスであり、これらの異なるプロパティがあります。 この情報を使用して、NHibernateには実際にこれをマップできる十分な容量があります。

次に、新しい学生オブジェクトが作成および初期化され、データベースに保存されるProgram.csファイルを示します。 次に、データベースからリストを取得します。

using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cache;
using NHibernate.Caches.SysCache;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;

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.Poor,

                  Address = new Location {
                     Street = "123 Street",
                     City = "Lahore",
                     Province = "Punjab",
                     Country = "Pakistan"
                  }
               };

               session.Save(student1);
               tx.Commit();
               var students = session.Query<Student>().ToList<Student>();
               Console.WriteLine("\nFetch the complete list again\n");

               foreach (var student in students) {
                  Console.WriteLine("{0} \t{1} \t{2} \t{3} \t{4} \t{5} \t{6} \t{7}",
                     student.ID,
                     student.FirstName,
                     student.LastName,
                     student.AcademicStanding,
                     student.Address.Street,
                     student.Address.City,
                     student.Address.Province,
                     student.Address.Country
                  );
               }
            }

            Console.ReadLine();
         }
      }
   }
}

これで、このアプリケーションを実行でき、NHibernateはそれらの値をデータベースに保存できます。 アプリケーションを実行すると、次の出力が表示されます。

Fetch the complete list again

2 Allan Bommer Poor 123 Street Lahore Punjab Pakistan

データベース内の値は次のとおりです。

値データベース

コンポーネントを使用すると、データベーステーブルにある列を独自の個別のクラスに分離できます。

  • ここで注目すべきもう1つの点は、Locationはクラスであり、エンティティではないためです。
  • これは値型オブジェクトであり、独自の主キーはありません。
  • それを含む生徒と同じテーブルに保存されます。
  • そのため、ここでコンポーネントを使用しています。
  • これにより、クラスレイヤー、クラスの定義方法とデータベースのレイアウト方法を柔軟に変更できます。