2
2

More than 1 year has passed since last update.

ODP.NET+C#でOracleに接続する

Last updated at Posted at 2021-09-20

はじめに

ポイントは以下の通り
 ・OracleはDockerで用意
 ・C#はローカルで用意

利用したdotnet コマンド

dotnet.ps1
# .NET Coreのコンソールアプリケーション作成
> dotnet new console --framework net5.0
# .NET Framework 4.7.2のコンソールアプリケーション作成
> dotnet new console --target-framework-override net472

# プログラム実行
> dotnet run
# プログラム実行(Release実行)
> dotnet run --configuration Release

# プロジェクト ファイルにパッケージ参照追加
> dotnet add package System.Collections
> dotnet add package System.IO
> dotnet add package Oracle.ManagedDataAccess --version 12.2.1100
> dotnet add package System.Data
# プロジェクト ファイルのパッケージ参照削除
> dotnet remove package System.Linq

# ファイルの追加はコマンドなしでそのまま配置

# デバッグ出力で不要な表示をさせないようにしたい
# デバッグ コンソールで「!シンボル」と入力

◆dotnet コマンド
 https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet

Programming

App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="Oracle.ManagedDataAccess.Client" />
      <add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </DbProviderFactories>
  </system.data>
</configuration>
ODPWrapper.cs
using Oracle.ManagedDataAccess.Client;
using System;
using System.Data;
using System.Data.Common;
 
public class ODPWrapper : IDisposable
{
    private DbProviderFactory _factory;
    private DbConnection _connection;
    private DbCommand _command;
    private DbTransaction _transaction;
 
    public ODPWrapper() : this("Data Source=localhost:9999/ORCLPDB1.localdomain;User ID=developer;Password=password"){}
 
    public ODPWrapper(string connectionString)
    {
        _factory = DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client");
        DbConnect(connectionString);

        //_connection = new OracleConnection(connectionString);
        //ConnectionString = connectionString;
    }
 
    public DbConnection DbConnect(string connectionString)
    {
        _connection = _factory.CreateConnection();
        _connection.ConnectionString = connectionString;
        return _connection;
    }
 
    public void Open()
    {
        if ((_connection.State == ConnectionState.Closed))
        {
            _connection.Open();
        }
    }
 
    void Close()
    {
        if (_connection.State == ConnectionState.Open)
        {
            _connection.Close();
        }
    }
 
    public DbCommand CreateCommand()
    {
        DbCommand cmd = _factory.CreateCommand();
        cmd.Connection = _connection;
        cmd.GetType().GetProperty("BindByName").SetValue(cmd, true, null);
        return cmd;
    }
 
    public DbCommand CreateCommand(string sql)
    {
        DbCommand cmd = CreateCommand();
        cmd.CommandText = sql;
        return cmd;
    }
 
    /// <summary>
    /// DataTableを返す
    /// </summary>
    /// <param name="sql"></param>
    public DataTable GetDataTable(string sql)
    {
        if (_command == null)
        {
            _command = CreateCommand();
        }
        _command.CommandText = sql;
        DbDataAdapter da = _factory.CreateDataAdapter();
        da.SelectCommand = _command;
        DataTable dt = new DataTable();
        da.Fill(dt);
        return dt;
    }
 
    /// <summary>
    /// SQLを実行する
    /// </summary>
    /// <param name="sql"></param>
    public int ExecuteSql(string sql)
    {
        if (_command == null)
        {
            _command = CreateCommand();
        }
        _command.CommandText = sql;
        Open();
        int result = _command.ExecuteNonQuery();
        if (_transaction == null || _transaction.Connection == null)
        {
            Close();
        };
        return result;
    }
 
    public DbDataReader ExecuteReader(string sql)
    {
        if (_command == null)
        {
            _command = CreateCommand();
        }
        _command.CommandText = sql;
        Open();
        DbDataReader result = _command.ExecuteReader(CommandBehavior.CloseConnection);
        // Close();
        return result;
    }
 
    public void BeginTransaction()
    {
        Open();
        _transaction = _connection.BeginTransaction();
    }
 
    public void Commit()
    {
        _transaction.Commit();
        Close();
    }
 
    public void Rollback()
    {
        _transaction.Rollback();
        Close();
    }
 
    #region IDisposable Support
    
    private bool _disposed = false;
 
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // マネージ オブジェクト破棄
                if (_transaction != null)
                {
                    _transaction.Dispose();
                }
                if (_command != null)
                {
                    _command.Dispose();
                }
                if (_connection != null)
                {
                    if (_connection.State == ConnectionState.Open)
                    {
                        _connection.Close();
                    }
                    _command.Dispose();
                }
            }
 
            // マネージ オブジェクト破棄
 
            _disposed = true;
        }
    }
 
    ~ODPWrapper() {
      Dispose(false);
    }
 
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion IDisposable Support

}
Program.cs
using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;

namespace OracleOperation2
{
    class Program
    {
        static void Main(string[] args)
        {
            // 引数操作
            if(args.Length > 0)
            {
              Console.WriteLine(args.Length);              
            }

            string dataSource = "localhost:9999/ORCLPDB1.localdomain";
            string connectString = "user id=developer;password=password;data source=" + dataSource;
            try
            {
                using (ODPWrapper odpWrapper = new ODPWrapper())
                {
                    // Update
                    //odpWrapper.ExecuteSql("UPDATE emp SET sal=sal*1.1 WHERE empno=7369");
                    
                    // Assert
                    Console.WriteLine("GetDataTable実行!!");

                    // Select
                    DataTable dt = odpWrapper.GetDataTable("SELECT * FROM tab");
                    Console.WriteLine("GetDataTable終わり!!");

                    //データテーブルの結果を出力
                    for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++)
                    {
                        for (int colIndex = 0; colIndex < dt.Columns.Count; colIndex++)
                        {
                            Console.Write(dt.Rows[rowIndex][colIndex].ToString());
                        }
                        Console.WriteLine();
                    }
                }

                // using (OracleConnection conn = new OracleConnection(connectString)) {
                //     try
                //     {
                //         conn.Open();
                //         System.Console.WriteLine("データベースに接続しました。");

                //         // データアクセス処理
                //         DbCommand cmd =  conn.CreateCommand();
                //         cmd.Connection = conn;
                //         cmd.CommandText = "SELECT * FROM tab";
                //         DbDataReader reader = cmd.ExecuteReader();
                //         while(reader.Read()){
                //             // 処理の実行
                //             System.Console.WriteLine(reader["TNAME"]);
                //         }
                //     }
                //     catch (Exception ex)
                //     {
                //         System.Console.WriteLine(ex.Message);
                //     }
                // }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine("★エラー:" + ex.Message);
            }


            // 読み込みたいCSVファイルのパスを指定して開く
            StreamReader sr = new StreamReader(@".\Resources\migrationTargetTable.csv");
            {
                Dictionary<string, string> csvData = new Dictionary<string, string>();

                // 末尾まで繰り返す
                while (!sr.EndOfStream)
                {
                    // CSVファイルの一行を読み込む
                    string line = sr.ReadLine();
                    // 読み込んだ一行をカンマ毎に分けて配列に格納する
                    string[] values = line.Split(',');
 
                    // 配列からリストに格納する
                    List<string> lists = new List<string>();
                    lists.AddRange(values);
 
                    // コンソールに出力する
                    foreach (string list in lists)
                    {
                        System.Console.Write("{0} ", list);
                    }
                    System.Console.WriteLine();
                }
            }
        }
    }
}

参考サイト

【事前準備】
 ◆.NET 5とVSCodeでデスクトップアプリ(ランチャー)
  https://qiita.com/Kosen-amai/items/dffd8070d4357f31ae7c
 ◆VSCodeでのGitの基本操作まとめ
  https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be
 ◆VSCodeで.NET Frameworkコンソールアプリをビルド&デバッグする
  https://qiita.com/hibara/items/fa66c3241293b7d43eae


 ◆NuGet Gallery | Oracle.ManagedDataAccess 21.3.0
  https://www.nuget.org/packages/oracle.manageddataaccess/
 ◆【.NET】Oracleクライアント不要なODP.NET Managed Driverの接続方法
  https://qiita.com/yaju/items/82df63b97a41720e197c
 ◆C# Oracleに接続してselectするサンプル
  https://itsakura.com/csharp-oracle
 ◆ADO.NET ORACLEでのSQL文内のパラメータの使い方
  https://www.oborodukiyo.info/ADONET/VS2017/ADONET-ParametersOfORACLE
 ◆空のプロジェクトからASP.NET MVC5 EntityFramework6 for Oracleを試す(SQL文を直接実行)
  https://qiita.com/yaju/items/798e9cf738cd52d0c457
 ◆ODP.NET ラッパー(Facade)クラスの作成
  http://nkurilog.blogspot.com/2017/12/odpnet-facade.html
 ◆Insert from C# into Oracle triggers doesn't execute
  https://stackoverflow.com/questions/29195475/insert-from-c-sharp-into-oracle-triggers-doesnt-execute
 ◆チュートリアル: Visual Studio Code を使用して .NET コンソール アプリケーションを作成する
  https://docs.microsoft.com/ja-jp/dotnet/core/tutorials/with-visual-studio-code
 ◆【C#】もう悩まない!CSV読み込みの最も簡単な方法を徹底解説
  https://www.sejuku.net/blog/85579
 ◆C#でCSVファイルを読み込んでコレクションに入れてみた
  https://water2litter.net/rye/post/c_io_read_csv/
 ◆VSCodeでC#開発をする方法
  https://zenn.dev/midoliy/articles/9e3cff958ff89ba151de

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2