ライブになったばかりのプロジェクトで EntityFramework を使用しています。ログによると、「無効な操作です。接続が切断されました」というエラーが 1 日に約 50 回発生しています。
例外は次のようになります。
An error occurred while executing the command definition. See the inner exception for details. at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at xxxx.SelectResultToPeople(IEnumerable`1 result)
at xxxx.GetResult()
at DynamicModule.ns.Wrapped_IPeopleGetter_a853d13914444ca6ab0e016e035520c5.<People_DelegateImplementation>__0(IMethodInvocation inputs, GetNextInterceptionBehaviorDelegate getNext)
Invalid operation. The connection is closed. at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
at System.Data.SqlClient.TdsParserStateObject.TryPeekByte(Byte& value)
at System.Data.SqlClient.SqlDataReader.TrySetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryCloseInternal(Boolean closeReader)
at System.Data.SqlClient.SqlDataReader.Close()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
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(CommandBehavior behavior)
at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
この例外は非常に特定のページでスローされるため、アプリケーション全体にランダムに分散されるわけではありません。これらのページの 1 つは、テーブル関数を使用してエンティティ フレームワークを介してデータベースに単純なクエリを作成します。テーブル関数は「GetPeopleNames」という名前で、ObjectContext クラスは「SiteEntities」という名前です。
public class PeopleGetter : IPeopleGetter
{
public List<object> GetResult()
{
using (var siteEntities = new SiteEntities())
{
IQueryable<someResultEntity> result =
siteEntities.GetPeopleNames()
.SortBy("Name", "asc")
.Skip(20*query.CurrentPagingPosition)
.Take(20);
List<People> people = SelectResultToPeople(result)
return people;
}
}
private List<People> SelectResultToPeople(IQueryable<someResultEntity> result)
{
return result
.ToList()
.Select(x => new People { })
.ToList();
}
}
なぜ私たちの障害と関係があるのか わかりませんが、PeopleGetter クラスが解決され、Unity IoC コンテナーによって作成されたことに言及したほうがよいでしょう。PeopleGetter は、次のように「PerRquest」LifeTimeManager に登録されます。
public class PerCallContextLifeTimeManager : HierarchicalLifetimeManager
{
private readonly string _key = string.Format("PerCallContextOrRequestLifeTimeManager_{0}", Guid.NewGuid());
public override object GetValue()
{
if (HttpContext.Current != null)
return GetFromHttpContext();
else
return base.GetValue();
}
private object GetFromHttpContext()
{
return HttpContext.Current.Items[_key];
}
public override void SetValue(object newValue)
{
if (HttpContext.Current != null)
SetInHttpContext(newValue);
else
base.SetValue(newValue);
}
private void SetInHttpContext(object newValue)
{
HttpContext.Current.Items.Add(_key, newValue);
}
public override void RemoveValue()
{
}
}
閉じた接続を取得している理由はありますか?
助けてくれてありがとう!