流NHなNHibernateずOracle

このトピックでは、 Oracleず共にFluent NHibernateラむブラリを匷調し、小さな䟋を挙げたいず思いたす 。 珟圚、このトピックに関する蚘事はほずんどなく ハブに関する蚀及、Oracleずの盞互䜜甚の説明はさらに少なくなっおいたす。 圓然、ほずんどはロシア語ではありたせん。 ただし、ラむブラリには泚意が必芁です。

著者は、XMLのNHibernateを取り陀くずいうタスクを蚭定したしたいわばxmlless。 したがっお、私たちのプロゞェクトではそうではありたせん。 絶察に。 代わりに、ラムダ匏ずメ゜ッドチェヌンを䜿甚しおデヌタベヌスを調敎し、゚ンティティをマップする、流な "fluid"たたは "flexible"むンタヌフェむスが提䟛されたす。

必芁条件


必芁なもの

将来の問題を回避するには、サヌドパヌティのナヌティリティなどを䜿甚しおデヌタベヌスに接続できるこずを確認しおください。 クラむアント蚭定は次の堎所にありたす。

%Oracle DAC/Client%\product\11.2.0\client_1\Network\Admin\tnsnames.ora

私の堎合、ファむルは次のようになりたす。
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = orasrvxp)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)

プロゞェクトを䜜成する


Visual Studio 2010で新しいコン゜ヌルプロゞェクトを䜜成し、FluentExampleずいう名前を付けたす。 NuGet Package Managerを䜿甚しお、必芁なパッケヌゞをすばやく芋぀け、受け取り、むンストヌルしたす。 ラむブラリを手動でむンストヌルするこずもできたす。

プロゞェクトファむルを右クリックし、[ラむブラリパッケヌゞ参照の远加...]をクリックしたす。 怜玢フィヌルドの[オンラむン]タブで、「fluent」ず入力したす。

リンクを远加

Fluent NHibernate自䜓に加えお、すべおの䟝存関係がロヌドされたすCastle.Core、Iesi.Collections、NHibernate、NHibernate.Castle。

私は、図曞通のりェブサむトのネむティブな䟋に基づいお、図曞通の機胜を簡単か぀十分に説明したす。 スキヌムの圢匏は次のずおりです。

プロゞェクトで、2぀のサブフォルダヌを䜜成したす゚ンティティヌずマッピング。ここに゚ンティティヌずそれに応じたマッピングが配眮されたす。

゚ンティティの説明


最初の゚ンティティ、埓業員。 埓業員には、名前、姓、および職堎がありたす。店です。 ゚ンティティフォルダヌで、次のコヌドを䜿甚しお新しいクラスを远加したす。
public class Employee
{
public virtual int Id { get ; private set ; }
public virtual string FirstName { get ; set ; }
public virtual string LastName { get ; set ; }
public virtual Store Store { get ; set ; }
}

* This source code was highlighted with Source Code Highlighter .

次の2぀の点に泚目しおください。

次に䞊んでいるのは、名前、䟡栌、およびそれらを販売する店舗のリストを持぀補品です。
public class Product
{
public virtual int Id { get ; private set ; }
public virtual string Name { get ; set ; }
public virtual double Price { get ; set ; }
public virtual IList<Store> StoresStockedIn { get ; private set ; }

public Product()
{
StoresStockedIn = new List <Store>();
}
}

* This source code was highlighted with Source Code Highlighter .

リストにはプラむベヌトセッタヌがあり、䞊蚘のようにコンストラクタヌで初期化が行われたす。

名前のある店舗のクラス、および商品ず埓業員のリスト
public class Store
{
public virtual int Id { get ; private set ; }
public virtual string Name { get ; set ; }
public virtual IList<Product> Products { get ; private set ; }
public virtual IList<Employee> Staff { get ; private set ; }

public Store()
{
Products = new List <Product>();
Staff = new List <Employee>();
}

public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add( this );
Products.Add(product);
}

public virtual void AddEmployee(Employee employee)
{
employee.Store = this ;
Staff.Add(employee);
}
}

* This source code was highlighted with Source Code Highlighter .

このクラスでは、NHibernateでは関連゚ンティティを保存する前に関係の䞡偎を定矩する必芁があるため、少しロゞックを説明したす。

ここで、゚ンティティの説明が終わりたす。 補品ずストア間の倚察倚の関係を実装するためのリンクテヌブルに぀いおは、以䞋で説明したす。

Mappim゚ンティティ


さらに、埓来のNHibernateを䜿甚する堎合は、xmlマッピングファむルずデヌタベヌス構成の䜜成を開始する必芁がありたす。 しかし、ここでFluent NHibernateが有効になりたす。

以䞋で説明するすべおのマッピングクラスは、Mappingsフォルダヌにありたす。 Employeeクラスを衚瀺するこずから始めたしょう。
using FluentExample.Entities;
using FluentNHibernate.Mapping;

namespace FluentExample.Mappings
{
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{

}
}
}

* This source code was highlighted with Source Code Highlighter .

衚瀺コヌド自䜓は、FluentNHibernateラむブラリのClassMapから継承したクラスのコンストラクタヌに配眮されClassMap 。 Fluent NHibernateがマッピングを芋぀けるためには、 public修食子でクラスを宣蚀する必芁がありたす。 すぐに完党なマッピングを怜蚎しおください。
public EmployeeMap()
{
Table( "Employee" );
Id(e => e.Id)
.GeneratedBy.Sequence( "Employee_seq" );
Map(e => e.FirstName);
Map(e => e.LastName);
References(e => e.Store);
}

* This source code was highlighted with Source Code Highlighter .

最初の行のTable() 、マップするテヌブルの名前を担圓したす。 以䞋に、名前を明瀺的に指定する理由を説明したす。

Id()メ゜ッドでは、オブゞェクトが識別するフィヌルドを瀺したすNHibernate <id> 。 自動むンクリメントでデヌタベヌスを䜿甚した堎合、Fluent NHibernateは自動的にタむプを認識し、IDゞェネレヌタヌNHibernate <generator> を割り圓おたす。 ただし、Oracleには自動むンクリメントがないため、メ゜ッドチェヌンの埌半で瀺されるシヌケンスを䜿甚したす。

次の2行は、タむプず名前が自動的に決定されるスカラヌプロパティNHibernate <property> の衚瀺を瀺しおいたす。 これは、プロパティの呜名芏則を䜿甚しお実装されたす。 Column()メ゜ッドを䜿甚しお列名を手動で指定するこずもできたすが、それでもデフォルトの芏則を䜿甚するか、独自の芏則を蚭定するこずをお勧めしたす。 契玄の詳现 。

次の行は、オブゞェクトが単数圢のStoreクラスを参照しおいるこず、぀たり、倚察倚の関係を実装しおいるこずを瀺しおいたす。 倖郚キヌ名は、やはり芏則に埓っお、Store_idず芋なされたす。 倖郚キヌ列は、 Column()メ゜ッドでオヌバヌラむドできたす。 References()メ゜ッドは、「倚くの」偎、リレヌションシップの反察偎「1぀」で䜿甚され、 HasMany() NHibernate <bag> メ゜ッドが䜿甚され、キヌフィヌルドの名前を倉曎するための察応するメ゜ッドはKeyColumn()です。

Table()メ゜ッドに戻りたしょう。 ここでのポむントは、デフォルトでは、テヌブル名を衚瀺するずき、Fluent NHibernateはそれらを匕甚笊契玄などで囲みたす。぀たり、テヌブルには匕甚笊ずずもに「Employee」ずいう名前が付けられたす。 Oracleでは、匕甚笊で囲たれた名前のみが倧文字ず小文字を区別したす。 この䟋では、匕甚笊を䜿甚せず、テヌブル名の倧文字ず小文字を区別せず、匕甚笊を付けないようにするため、明瀺的に瀺したした。

ストアのマッピングに移りたしょう。
public class StoreMap : ClassMap<Store>
{
public StoreMap()
{
Table( "Store" );
Id(x => x.Id)
.GeneratedBy.Sequence( "Store_seq" );
Map(x => x.Name);
HasMany(x => x.Staff)
.Inverse()
.Cascade.All();
HasManyToMany(x => x.Products)
.Cascade.All()
.Table( "StoreProduct" );
}
}

* This source code was highlighted with Source Code Highlighter .

ここで、前述のEmployeeクラスの察称的なHasMany()呌び出しを確認したす。 HasManyToMany()メ゜ッドも䜿甚されたす。これは、 Table()メ゜ッドによっおチェヌンで名前が指定された䞭間テヌブルを介しお、ストアず補品の間の倚察倚の関係を実装したす。

Inverse()メ゜ッドは、コレクションの所有者がリレヌションシップのもう䞀方の端、぀たりEmployeeクラスであり、最初に保存されるこずを瀺しおいたす。 Cascade.All()は、むベントを関連アむテムに枡したす。 ぀たり、たずえばストアを削陀するず、このストアの補品およびすべおの埓業員ずの通信もすべお削陀されたす。 詳现に぀いおは、NHibernateのドキュメントを参照しおください。

最埌に、補品を衚瀺したす。
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Table( "Product" );
Id(x => x.Id)
.GeneratedBy.Sequence( "Product_seq" );
Map(x => x.Name);
Map(x => x.Price);
HasManyToMany(x => x.StoresStockedIn)
.Cascade.All()
.Inverse()
.Table( "StoreProduct" );
}
}

* This source code was highlighted with Source Code Highlighter .

以前のマッピングの経隓から、ここで新しいものを芋぀けられないこずを願っおいたす。 流fluentなマッピングの詳现をご芧ください 。

次に、Oracleぞの接続を蚭定したす。

Oracleに接続する


connectionStringを䜿甚しお接続したす。 プロゞェクトに新しいファむルApp.configを远加し、流hなナヌザヌの接続文字列をnhibernateパスワヌドで入力したす
Copy Source | Copy HTML
  1. < xml バヌゞョン = "1.0" encoding = "utf-8"  >
  2. < 蚭定 >
  3. < connectionStrings >
  4. < 名前を 远加 =「Oracle」
  5. connectionString = "DATA SOURCE = orcl; PASSWORD = nhibernate; PERSIST SECURITY INFO = True;ナヌザヌID = fluent"
  6. providerName = "Oracle.DataAccess.Client" />
  7. </ connectionStrings >
  8. </ 蚭定 >

次に、遞択したプロバむダヌに付属するOracle.DataAccessアセンブリぞのリンクを远加する必芁がありたす。



リンクを远加するためのダむアログはおそらく異なるでしょう-私は生産性向䞊ツヌルを䜿甚しおいたす 。

远加されたリンクプロパティCopy Local = True蚭定しCopy Local = True 。これは、プロゞェクトのバむナリ出力ファむルを含むフォルダヌにこのラむブラリをコピヌする必芁があるこずを瀺したす。



䟿宜䞊、小さなヘルパヌを䜿甚しおFluent NHibernateでセッションを開きたす。
using FluentExample.Entities;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Driver;

namespace FluentExample
{
public static class FluentNHibernateHelper
{
private static ISessionFactory _sessionFactory;
public static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null )
{
var dbConfig = OracleDataClientConfiguration.Oracle10
.ConnectionString(c => c.FromConnectionStringWithKey( "Oracle" ))
.Driver<OracleDataClientDriver>()
.ShowSql();

_sessionFactory = Fluently.Configure()
.Database(dbConfig)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Employee>())
.BuildSessionFactory();
}
return _sessionFactory;
}
}

public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
}

* This source code was highlighted with Source Code Highlighter .

デヌタベヌス構成では、 OracleDataClientConfiguration名前空間の定矩枈みクラスOracleDataClientConfigurationを䜿甚し、䜜成した接続文字列ずNHibernateドラむバヌを䜿甚するように構成したす。 生成されたSQLク゚リを衚瀺するオプションを有効にするこずもできたす。 デヌタベヌス構成の詳现 。

次に、NHibernate自䜓の構成を実行したす。 デヌタベヌス構成を眮き換え、マッピングの゜ヌスを瀺し、セッションファクトリを芁求したす。 Fluent Configurationの詳现をご芧ください 。

この段階で、セッションの取埗は成功するはずです。
class Program
{
static void Main()
{
using (FluentNHibernateHelper.OpenSession())
{

}
}
}

* This source code was highlighted with Source Code Highlighter .

ベヌスのテスト


これで、プロゞェクトは次のような構造になりたす。



実際のテストを実行したす。
private static void Main()
{
using ( var session = FluentNHibernateHelper.OpenSession())
{
using ( var transaction = session.BeginTransaction())
{
var barginBasin = new Store { Name = "Bargin Basin" };
var superMart = new Store { Name = "SuperMart" };

var potatoes = new Product { Name = "Potatoes" , Price = 3.60 };
var fish = new Product { Name = "Fish" , Price = 4.49 };
var milk = new Product { Name = "Milk" , Price = 0.79 };
var bread = new Product { Name = "Bread" , Price = 1.29 };
var cheese = new Product { Name = "Cheese" , Price = 2.10 };
var waffles = new Product { Name = "Waffles" , Price = 2.41 };

var daisy = new Employee { FirstName = "Daisy" , LastName = "Harrison" };
var jack = new Employee { FirstName = "Jack" , LastName = "Torrance" };
var sue = new Employee { FirstName = "Sue" , LastName = "Walkters" };
var bill = new Employee { FirstName = "Bill" , LastName = "Taft" };
var joan = new Employee { FirstName = "Joan" , LastName = "Pope" };

// . ,
// many-to-many.
AddProductsToStore(barginBasin, potatoes, fish, milk, bread, cheese);
AddProductsToStore(superMart, bread, cheese, waffles);

//
AddEmployeesToStore(barginBasin, daisy, jack, sue);
AddEmployeesToStore(superMart, bill, joan);

//
session.SaveOrUpdate(barginBasin);
session.SaveOrUpdate(superMart);

transaction.Commit();
}

//
using (session.BeginTransaction())
{
var stores = session.CreateCriteria( typeof (Store)). List <Store>();
foreach ( var store in stores)
WriteStorePretty(store);
}

Console .ReadKey();
}
}

public static void AddProductsToStore(Store store, params Product[] products)
{
foreach ( var product in products)
store.AddProduct(product);
}

public static void AddEmployeesToStore(Store store, params Employee[] employees)
{
foreach ( var employee in employees)
store.AddEmployee(employee);
}

private static void WriteStorePretty(Store store)
{
Console .WriteLine(store.Name);
Console .WriteLine( " Products:" );

foreach ( var product in store.Products)
Console .WriteLine( " " + product.Name);

Console .WriteLine( " Staff:" );
foreach ( var employee in store.Staff)
Console .WriteLine( " " + employee.FirstName + " " + employee.LastName);

Console .WriteLine();
}

* This source code was highlighted with Source Code Highlighter .

以䞊です。
Oracleで回路を生成するスクリプトも提䟛したす。

次は


未実珟の機胜


著者は、ネむティブラむブラリの機胜の倧郚分をサポヌトしおいたすが、NHibernateの䞀郚の機胜、たずえば<sql-insert>はただ利甚できたせん。

自動マッピング


Fluent NHibernateを䜿甚するず、入力された芏則に埓うか、独自の芏則を定矩するだけで、自動的にマッピングを行うこずができたす。

マッピングテスト


このラむブラリを䜿甚するず、䜜成したマッピングをすばやく同じスタむルでテストできたす。

完党なAPIドキュメント

Source: https://habr.com/ru/post/J125135/


All Articles