0

StructureMapを使用DBして、リポジトリにLINQデータコンテキスト(クラス)を挿入し、サービスレイヤーを介してクエリされるHTTPコンテキストベースの読み取りクエリを実行しています。「Broken」ConnectionExecuteReaderエラーが発生するまで、数時間はすべて正常に動作します(完全なダンプについては以下を参照してください)。

書き込みクエリ(読み取りクエリではない)はusing (var db = new DB()) {...}ステートメントにラップされていますが、これが問題の原因になるとは思われません。

MultipleActiveResultSets=true;しばらくの間問題を解決したように見える接続文字列に追加しましたが、アプリケーションプールをリサイクルするまでエラーが返され、一時的に問題が解決します。おそらく、プールをリサイクルすると、すべての「壊れた」データコンテクストが解放されます。

StructureMapは、HTTPコンテキストごとにデータコンテキストとリポジトリを挿入するように構成されています。

For<DB>().HttpContextScoped().Use(new DB());
For<IUserRepository>().HttpContextScoped().Use<SqlUserRepository>();

データコンテキストは、次のようにユーザーリポジトリによって消費されます。

private DB _db;
public SqlUserRepository(DB db)
{
    _db = db;
}

これは、次のようにデータコンテキストを便利にクエリします。

public IQueryable<User> GetUsers()
{
    var users = from u in _db.Users
                select u; // omitted the rest
}

数時間後、この恐ろしいエラーが発生します。

System.InvalidOperationException: ExecuteReader requires an open and available 
Connection. The connection's current state: Broken. at 
System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) at 
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior 
runBehavior, Boolean returnStream, String method, DbAsyncResult result) at 
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior 
runBehavior, Boolean returnStream, String method) at 
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at 
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at 
System.Data.Common.DbCommand.ExecuteReader() at 
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, 
IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] 
subQueries, Object lastResult) at 
System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, 
IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) at 
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expressi
on query) at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression 
expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source) at 
MyApp.Data.SqlUserRepository.GetUser(String username) at 
MyApp.Services.BranchService.GetUser(String username) at 
MyApp.Controllers.BranchController.get_CurrentUser() at 
MyApp.Controllers.BranchController.OnActionExecuting(ActionExecutingContext filterContext) 
at 
System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuting(ActionExecutingCon
text filterContext) at 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, 
ActionExecutingContext preContext, Func`1 continuation) at 
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<>c__DisplayClassf.b__c() at 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext 
controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 
parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext 
controllerContext, String actionName)

どうすればこれを解決できますか?すべてのクエリをusingステートメントで手動でラップする必要はありません。

4

4 に答える 4

3

意図せずにコンテキストのシングルトンを作成しているようです:

For<DB>().HttpContextScoped().Use(new DB());

リクエストごとに新しいコンテキストを作成するには、代わりにこれを使用します。

For<DB>().HttpContextScoped().Use(() => new DB());
于 2011-03-10T12:06:00.877 に答える
1

何らかの理由で使用できない場合を除き、リポジトリごとに新しい DataContext を使用するだけです。この質問を参照してください: StructureMap / ASP.MVC / Visual Studio / LinqToSql での奇妙な動作

于 2011-03-09T17:01:37.077 に答える
0

Your GetUsers method is returning an IQueryable, meaning the data will not be retrieved from the database until something iterates over it. If you return the IQueryable, close your data reader, and then attempt to iterate over the data, you will get an error, because the connection is closed.

于 2011-03-09T18:54:45.607 に答える
0

この理由の 1 つは、接続をまったく開くことができなかったことです。「SqlConnection.Open」ステートメントで発生する例外はすべて抑制されています。問題がアプリケーションにない場合は、サーバーが接続を許可できない可能性があります。アプリまたは同じサーバーでホストされている他のデータベースでの接続リークが原因である可能性があります。

于 2011-12-21T18:43:02.597 に答える