ADO.NET Entity Frameworkを使用してOracleデータベースにアクセスする


良い一日。

ソフトウェアを開発するとき、それは常に単純なルールに導かれ、サードパーティのコンポーネント、プラットフォーム、開発プロジェクトで使用されるテクノロジーが少ないほど良い。 独創的なものはほとんどすべてシンプルです。 残念ながら、開発者は常に、使用するツールとシステムを自由に選択できる機会があるわけではありません。 そこで、Windows Forms + ODAC + Oracle DB Serverプロジェクトを入手しました。

Microsoft Entity FrameworkおよびLINQ to Entities(Beta2)向けOracle Data Access Components(ODAC)のリリースについて聞いてうれしく思いました。 私は本当にこの瞬間を楽しみにしていたのです。 サードパーティのORMは使用できません-すべてがターンキーです。

エンドマシンにインストールされたODACクライアントを介してEntity Frameworkを使用するようにアプリケーションに教える方法については、 Oracleの手順を追った説明で説明されています 。 ユーザーのマシンにOracleクライアントをインストールする必要性を取り除く方法を誰が気にしているのか、私はcatの下で尋ねます。

一般的な要件



ユーザーシステムへ:
  1. MS Windows XP SP3以上のOS
  2. Microsoft .NET Framework 4
  3. オプションで135 MBの空きディスク容量

開発者のシステムへ:
  1. Visual Studio 2010 Service Pack 1
  2. Oracle Databaseサーバー9.2以上
  3. ODAC for Microsoft Entity FrameworkおよびLINQ to Entities


プラグインライブラリ

Oracleデータベースへのアクセスを整理するには、ODAC.NETパッケージから次のライブラリをプロジェクトに追加する必要があります。ライブラリ「client path」\ client_1 \ odp.net \ bin \ 4 \ Oracle.DataAccess.dll (〜1.4 MB)を参照として接続します。 「 ローカルコピー 」プロパティを「 true 」に設定します。

次のファイルをプロジェクトに追加し、「 出力ディレクトリにコピー 」プロパティ新しい場合にコピー 」に設定するだけです。

接続文字列は、tnsnames.oraファイルにあるもののようになります。

データソース=(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = ServerNameOrIP)(PORT = PortNumber)))(CONNECT_DATA =(SERVICE_NAME = DBName))); User Id = UserName; Password = UserPa $$ w0rd;

これは、ユーザーのマシンにクライアントをインストールせずにデータベースへのアクセスを提供するのに十分です。
private bool TestConnect()
{
try
{
var oracleConnection = new OracleConnection
{
ConnectionString =
"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ServerNameOrIP)(PORT=PortNumber)))(CONNECT_DATA=(SERVICE_NAME=DBName)));User Id=UserName;Password=UserPa$$w0rd;"
};
oracleConnection.Open();
var oracleCommand = new OracleCommand
{
CommandText = "select sysdate from dual" ,
Connection = oracleConnection,
Transaction = null
};
var oracleDataAdapter = new OracleDataAdapter {SelectCommand = oracleCommand};
var sysDateDataSet = new DataSet( "SomeName" );
oracleDataAdapter.Fill(sysDateDataSet, "dateTimeTable" );
return sysDateDataSet.Tables[0].Rows.Count > 0;
}
catch (Exception exx)
{
MessageBox.Show( string .Format( "Could not connect directly to an Oracle database: \n {0}" , exx.Message));
return false ;
}

* This source code was highlighted with Source Code Highlighter .

OracleクライアントをインストールせずにEntity Frameworkモデルを使用するために必要なこと

独自のADO.NET Entity Data Modelを作成するか、例のように「HRModel」と「HREntities」コンテキストを作成します。 これを行うには、 上記のOracleマニュアルに示されいるように追加ウィザードを使用します

Oracleデータベースに接続するための行は、プロジェクト構成ファイル(App.Config / Web.Config)に自動的に追加されます(ウィザードでこの項目を選択した場合)。
< add name ="HREntities" connectionString ="metadata=res://*/HRModel.csdl|res://*/HRModel.ssdl|res://*/HRModel.msl;provider=Oracle.DataAccess.Client;provider connection string="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ServerNameOrIP)(PORT=PortNumber)))(CONNECT_DATA=(SERVICE_NAME=DBName)));User Id=UserName;Password=UserPa$$w0rd;"" providerName ="System.Data.EntityClient" />

ここでは、「 プロバイダー接続文字列 」属性に割り当てられた値は二重引用符で囲む必要があるという事実に特に注意を払う価値があります(それらを示すには&_q_u_o_tコードを使用する必要があります)。 接続文字列を動的に形成する場合も考慮する価値があります。

次に、 プロジェクト構成ファイルで、システムに既に登録されているものにデータプロバイダーを追加するセクションを作成する必要があります。そのリストはファイル「%windir%\ Microsoft.NET \ Framework \ v4.0.30319 \ Config \ machine.config」にあります。 ODACがマシンにインストールされている場合、 「Oracle.DataAccess.Client」プロバイダーはシステム構成ファイルに既に登録されており、プロバイダーを追加しようとすると、アプリケーションの起動時にエラーが発生します。 '一意であるように制限されています。 値「Oracle.DataAccess.Client」はすでに存在しています。」

これを防ぐには、タグを使用します
< remove invariant = "Oracle.DataAccess.Client" />
Oracle.DataAccess.Clientプロバイダーは、存在する場合、データプロバイダーのリストから削除されます。 次に、サプライヤーを追加します。 システムに登録されているEntityClientプロバイダーのリストに追加されます。
< system.data >
< DbProviderFactories > <br> < remove invariant ="Oracle.DataAccess.Client" />
< add name ="Oracle.DataAccess.Client" invariant ="Oracle.DataAccess.Client" description ="Oracle Data Provider for .NET" type ="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.2.40, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</ DbProviderFactories >
</ system.data >


微妙

MSの「正しい」メソッドを使用してモデルをデータベースに動的に接続する場合、EntityConnectionStringBuilderオブジェクトを介した接続文字列の形成がまったく正しくないことに注意する必要があります。
string providerName = "Oracle.DataAccess.Client" ;
string dataSourse = (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ServerNameOrIP)(PORT=PortNumber)))(CONNECT_DATA=(SERVICE_NAME=DBName)));User Id=UserName;Password=UserPa$$w0rd;”;
var sqlBuilder =
new SqlConnectionStringBuilder
{
DataSource = dataSourse
};
string providerString = sqlBuilder.ToString();
var entityBuilder =
new EntityConnectionStringBuilder
{
Provider = providerName,
ProviderConnectionString = providerString,
Metadata =
@"res://*/HRModel.csdl|res://*/HRModel.ssdl|res://*/HRModel.msl"
};
using ( var conn =
new EntityConnection(entityBuilder.ToString()))
{
conn.Open();
Console .WriteLine( "Just testing the connection." );
conn.Close();
}

* This source code was highlighted with Source Code Highlighter .

その結果、entityBuilder.ToString()は、プロバイダー接続文字列属性の値を完全に囲む余分な単一引用符付きの接続文字列を返します
metadata=…;provider=Oracle.DataAccess.Client;provider connection string= ' Data Source= \" (DESCRIPTION=(… ); User Id=UserName;Password=UserPa$$w0rd; \"'

Oracleプロバイダーには、次の形式の接続文字列が必要です。
metadata=…;provider=Oracle.DataAccess.Client;provider connection string= \" Data Source=(DESCRIPTION(…); User Id=UserName;Password=UserPa$$w0rd; \"

-それ以外の場合、エラーが発生します。
接続文字列をいものにできますが:
private bool DynamicConnect()
{
const string providerName = "Oracle.DataAccess.Client" ;
const string serverName = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ServerNameOrIP)(PORT=PortNumber)))(CONNECT_DATA=(SERVICE_NAME=DBName)));User Id=UserName;Password=UserPa$$w0rd;" ;
const string metadata = "metadata=res://*/HRModel.csdl|res://*/HRModel.ssdl|res://*/HRModel.msl" ;
var entBild = string .Format( "metadata={0};provider={1};provider connection string=\"Data Source={2}\";" , metadata, providerName, serverName);
try
{
var conn = new EntityConnection(entBild);
conn.Open();
var hrEntities = new HREntities(conn);
var tmpResult = hrEntities.BRIDGE.Count();
conn.Close();
return true ;
}
catch (Exception exx)
{
MessageBox.Show( string .Format( "Could not connect directly to an Oracle database: \n {0}" , exx.Message));
return false ;
}
}


* This source code was highlighted with Source Code Highlighter .

多分それはベータ版のエコーです-Oracleが約束するように、2011年の第4四半期に開催されるリリースでそれがどうなるか見てみましょう。


その結果、アセットに書き込むことができます。


負債に入力することができます:

近い将来、Microsoft Entity Framework + OracleとSystem.Data.SqlClient + MS SQL ServerのODACを介した作業の速度を比較したいという要望があります。

お時間をいただきありがとうございます。

トピックのソースのリスト:

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


All Articles