Closeメソッドを明示的に呼び出すか、Usingステートメントで接続を実行すると、接続を閉じる必要がありますか?接続をオープンにしておくと、接続の再利用が可能になり、将来のクエリでSQLパフォーマンスが向上しますか?Dapperを使用するときに接続を閉じる
答えて
Dapperの最新バージョンを使用していることを前提としています。 Dapperので
、接続を管理する方法は2つあります。
は完全に自分自身を管理する: ここでは、開閉接続のために完全に責任があります。これは、ADO.NETを使用しているときに接続を処理する方法と同じです。
Dapperのは、それを管理することを許可する: Dapperのは、自動的に(それが開かれていなかった場合)の接続を開き、(それがDapperので開かれた場合)あなたのためにそれを閉じます。これは
DataAdapter.Fill()
メソッドに似ています。私は個人的にこの方法をお勧めしません。これは毎回適用されるわけではありません。以下はマルクGravellはこの回答のためcommentの一つにこう言われる、https://stackoverflow.com/a/12629170/5779732
だけでなく、クローズ/技術的に開いているが配置さとは異なっています。個々の通話の周りだけで開閉するつもりなら、あなたはそれを行うこともできます。 より広い粒度(例えば要求ごとに)で開閉するならば、あなたのコードがそれを行い、dapperに対してオープンな接続を渡す方が良いでしょう。
もちろん、1回の接続で複数のクエリを呼び出すことができます。ただし、リソースのリークを避けるために、接続は(Close()
、Dispose()
メソッドを呼び出すか、using
ブロックに囲んで)終了する必要があります。接続を閉じると、接続プールに戻ります。接続プールを使用すると、新しい接続コストよりもパフォーマンスが向上します。
接続を処理するだけでなく、トランザクションを管理するためにUnitOfWorkを実装することをお勧めします。 GitHub上のthis優れたサンプルを参照してください。
次のソースコードを参考にしてください。これは私のニーズのために書かれていることに注意してください。それはあなたのためにはうまくいかないかもしれません。
public sealed class DalSession : IDisposable
{
public DalSession()
{
_connection = new OleDbConnection(DalCommon.ConnectionString);
_connection.Open();
_unitOfWork = new UnitOfWork(_connection);
}
IDbConnection _connection = null;
UnitOfWork _unitOfWork = null;
public UnitOfWork UnitOfWork
{
get { return _unitOfWork; }
}
public void Dispose()
{
_unitOfWork.Dispose();
_connection.Dispose();
}
}
public sealed class UnitOfWork : IUnitOfWork
{
internal UnitOfWork(IDbConnection connection)
{
_id = Guid.NewGuid();
_connection = connection;
}
IDbConnection _connection = null;
IDbTransaction _transaction = null;
Guid _id = Guid.Empty;
IDbConnection IUnitOfWork.Connection
{
get { return _connection; }
}
IDbTransaction IUnitOfWork.Transaction
{
get { return _transaction; }
}
Guid IUnitOfWork.Id
{
get { return _id; }
}
public void Begin()
{
_transaction = _connection.BeginTransaction();
}
public void Commit()
{
_transaction.Commit();
Dispose();
}
public void Rollback()
{
_transaction.Rollback();
Dispose();
}
public void Dispose()
{
if(_transaction != null)
_transaction.Dispose();
_transaction = null;
}
}
interface IUnitOfWork : IDisposable
{
Guid Id { get; }
IDbConnection Connection { get; }
IDbTransaction Transaction { get; }
void Begin();
void Commit();
void Rollback();
}
ここで、リポジトリは何らかの方法でこのUnitOfWorkを受け入れる必要があります。私はConstructorでDependency Injectionを選択します。
public sealed class MyRepository
{
public MyRepository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
IUnitOfWork unitOfWork = null;
//You also need to handle other parameters like 'sql', 'param' ect. This is out of scope of this answer.
public MyPoco Get()
{
return unitOfWork.Connection.Query(sql, param, unitOfWork.Transaction, .......);
}
public void Insert(MyPoco poco)
{
return unitOfWork.Connection.Execute(sql, param, unitOfWork.Transaction, .........);
}
}
そして、あなたはこのようにそれを呼び出す:代わりに、直接呼び出しでの接続をさらすこと、
using(DalSession dalSession = new DalSession())
{
//Your database code here
MyRepository myRepository = new MyRepository(dalSession.UnitOfWork);//UoW have no effect here as Begin() is not called.
myRepository.Insert(myPoco);
}
この方法:トランザクションに
:
using(DalSession dalSession = new DalSession())
{
UnitOfWork unitOfWork = dalSession.UnitOfWork;
unitOfWork.Begin();
try
{
//Your database code here
MyRepository myRepository = new MyRepository(unitOfWork);
myRepository.Insert(myPoco);
//You may create other repositories in similar way in same scope of UoW.
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
トランザクションなしコード、あなたは1つの場所でそれを制御します。
上記のコードのリポジトリの詳細は、hereを参照してください。
UnitOfWork
はちょうどトランザクションよりもmoreです。このコードはトランザクションだけを処理します。このコードを拡張して、追加の役割をカバーすることができます。
- 1. MongoEngine:接続を閉じる
- 2. ユーザがブラウザを閉じるときにSocket.ioが接続を閉じない
- 3. JMSを使用するWebsphere MQ、MQで閉じた接続を閉じた
- 4. Websocketとメッセージの接続を閉じる
- 5. JavaとWebSocket接続を閉じる
- 6. urlretrieveを使用した後にftp接続を閉じる
- 7. Androidアプリを離れるときFirebaseデータベース接続を閉じる
- 8. NSOutputStreamが終了したときに接続を閉じる
- 9. 接続を閉じるには
- 10. Zehon FTP接続を閉じるには
- 11. Ruby:SOAP4R接続を閉じるには?
- 12. Java SQLite - 接続を閉じるには?
- 13. 閉じるMQ接続
- 14. PHPRedisとPHP-FPMを使用しているときにpconnect()接続を閉じるかリセットするには?
- 15. 下にある接続が閉じられました:HttpWebRequestを使用しているときに予期せず接続が閉じられました
- 16. Windows Cソケット閉じると再接続
- 17. spring-amqpを使用したRabbit MQブローカーとの接続を閉じるには
- 18. WCF - クライアントが接続されているときに閉じると、CloseTimeout期間のServiceHostブロックを閉じます。
- 19. JavaソケットHTTP 1.0接続を閉じる
- 20. githubアプリケーションへの接続を閉じる
- 21. Webサービスクライアントで接続を閉じる
- 22. SparkのMYSQL JDBC接続を閉じる
- 23. Mqttブローカー、古い接続を閉じる
- 24. C#データベース接続を閉じる
- 25. WebSocket接続エラーを閉じる
- 26. ウェブサイトの接続を閉じる
- 27. Pythonでソックス/プロキシ接続を閉じる
- 28. OPC DA接続を閉じる
- 29. ResultSetを閉じるとjava内の接続が閉じられる
- 30. MariaexとElixirとの接続を閉じるには
私はあなたの意見について完全に同意できません。接続を管理するためにdapperを使用する方がよい場合もあります。私はMarc Gravellをhttps://stackoverflow.com/a/12629170/1262198から引用したいと思っています。 "技術的にオープン/クローズドは処分と異なります。個々のコールの周りを開閉するだけの場合は、あなたがより広い粒度(例えばリクエストごとに)で開閉しているなら、あなたのコードがそれを行い、dapperにオープンな接続を渡す方が良いでしょう。 – Arvand
@Arvand:同意します。私は自分の答えを修正した。私はこれが毎回適用されないかもしれないということを意味します。 –