Я недавно использовал новую инфраструктуру MVC с StructureMap и в целом добился хороших результатов, однако продолжаю сталкиваться с очень странной ошибкой, которую не могу понять или решить, как ее устранить.
Это моя архитектура:
- DBContext - контекст данных linqToSql.
- IRepository - контракт, определяющий методы данных.
- IService - договор, определяющий методы обслуживания.
- Контроллеры - два в этом примере.
Поэтому у меня есть:
public class Repo : IRepository
{
public Repo(DBContext db)
{
.....
}
}
public class Service : IService
{
public Service(IRepository repo)
{
.....
}
}
public class ControllerOne : Controller
{
public ControllerOne(IService service)
{
.....
}
}
public class ControllerTwo : Controller
{
public ControllerTwo(IService service)
{
.....
}
}
StructureMap используется для определения конкретных типов для IRepository и IService, а DBContext создается с помощью выражения lamba - () => new DBContext (), настроенного реестром DSL.
В настоящее время нет кэширования DBContext
На проблему:
Моя страница индекса загружается и выполняет два одновременных Ajax-запроса к ControllerOne и ControllerTwo, которые создаются через фабрику контроллеров StructureMap из MvcContrib.
StructureMap внедряет конкретные типы IService, которые, в свою очередь, создаются с настроенным экземпляром IRepository и новым объектом DBContext.
ControllerOne запрашивает модель из экземпляра IService, который затем возвращается как JsonActionResult, который отображается Newtonsoft.Json.
ControllerTwo запрашивает другую модель из экземпляра IService, которая также сериализуется в объект Json, когда среда MVC выполняет ActionResult.
Я управляю сайтом через Cassini в VS2008.
Проблема, с которой я сталкиваюсь время от времени, - это ошибка, генерируемая из LinqToSql
- данные не могут быть прочитаны, читатель уже открыт или
- не может загрузить данные в таблицу данных, так как данные уже существуют (в настоящее время у меня нет точных исключений, но оба они являются внутренними для LinqToSql).
Если ошибка возникает в ControllerOne, то ControllerTwo также завершится ошибкой с аналогичной ошибкой, как если бы два запроса выполнялись с общими объектами.
Это не всегда ошибка, но этого достаточно, чтобы меня беспокоить моя архитектура и то, что она каким-то образом настроена неправильно.
Может ли StructureMap возвращать один и тот же экземпляр ControllerOne и ControllerTwo при последующих запросах или каким-либо образом кэшировать DBContext? Даже если я не прошу этого?
Кто-нибудь видел что-нибудь подобное при работе в Visual Studio / Cassini? Помогает ли прохождение через IIS?
Должен ли я удалить LinqToSql?
Закрытие Visual Studio и повторное открытие часто могут на некоторое время решить проблему.
Большое спасибо, если кто-нибудь может пролить свет на проблему.
РЕДАКТИРОВАТЬ: Включая фрагмент журнала из файла журнала NLog (идентификатор потока номер перед точкой с запятой):
03/20/2009 01:40:32 12: controller=Timesheet,date=2001-05-06,Action=WeekEnding /beta/Timesheet/2001-05-06?_dc=1237513232397
03/20/2009 01:40:32 10: controller=Timesheet,date=2001-05-06,Action=WeekEnding /beta/Timesheet/2001-05-06?_dc=1237513232449
03/20/2009 01:40:32 10: There is already an open DataReader associated with this Command which must be closed first. System.InvalidOperationException[br] at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
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(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
at HCD.Intranet.Core.Data.Linq.LinqEmployeeRepository.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding, Int32 nonProjectId)
at HCD.Intranet.Core.Services.Impl.EmployeeService.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding)
at HCD.Intranet.Core.Models.Timesheet.CalculateHolidaysRemaining()
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteTimesheet(JsonWriter writer, Timesheet timesheet)
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteJson(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.WriteMemberInfoProperty(JsonWriter writer, Object value, JsonMemberMapping memberMapping)
at Newtonsoft.Json.JsonSerializer.SerializeObject(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
at HCD.Intranet.Core.Web.Mvc.NewtonsoftJsonResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
03/20/2009 01:40:32 12: Invalid attempt to call Read when reader is closed. System.InvalidOperationException[br] 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(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
at HCD.Intranet.Core.Data.Linq.LinqEmployeeRepository.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding, Int32 nonProjectId)
at HCD.Intranet.Core.Services.Impl.EmployeeService.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding)
at HCD.Intranet.Core.Models.Timesheet.CalculateHolidaysRemaining()
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteTimesheet(JsonWriter writer, Timesheet timesheet)
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteJson(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.WriteMemberInfoProperty(JsonWriter writer, Object value, JsonMemberMapping memberMapping)
at Newtonsoft.Json.JsonSerializer.SerializeObject(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
at HCD.Intranet.Core.Web.Mvc.NewtonsoftJsonResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
03/20/2009 01:41:58 12: controller=Timesheet,month=6,year=2001,Action=Calendar /beta/Timesheet/Calendar/6/2001?_dc=1237513318470
03/20/2009 01:41:59 10: controller=Timesheet,date=2001-06-03,Action=WeekEnding /beta/Timesheet/2001-06-03?_dc=1237513318509
03/20/2009 01:41:59 12: The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type. System.InvalidOperationException[br] at Read_TimesheetEntry(ObjectMaterializer`1 )
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at HCD.Intranet.Core.Data.Linq.LinqTimesheetRepository.GetEntries(Int32 timesheetHeaderId)
at HCD.Intranet.Core.Services.Impl.TimesheetService.GetEntries(Int32 timesheetHeaderId)
at HCD.Intranet.Core.Models.Timesheet.get_InnerEntries()
at HCD.Intranet.Core.Models.TimeMap..ctor(Timesheet timesheet)
at HCD.Intranet.Core.Models.Json.TimesheetCalendarJsonConverter.WriteTimesheet(JsonWriter writer, Timesheet[] timesheets)
at HCD.Intranet.Core.Models.Json.TimesheetCalendarJsonConverter.WriteJson(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
at HCD.Intranet.Core.Web.Mvc.NewtonsoftJsonResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
03/20/2009 01:41:59 12: controller=Timesheet,date=2001-06-03,Action=WeekEnding /beta/Timesheet/2001-06-03?_dc=1237513318545
03/20/2009 01:41:59 12: There is already an open DataReader associated with this Command which must be closed first. System.InvalidOperationException[br] at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
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(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
at HCD.Intranet.Core.Data.Linq.LinqEmployeeRepository.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding, Int32 nonProjectId)
at HCD.Intranet.Core.Services.Impl.EmployeeService.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding)
at HCD.Intranet.Core.Models.Timesheet.CalculateHolidaysRemaining()
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteTimesheet(JsonWriter writer, Timesheet timesheet)
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteJson(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.WriteMemberInfoProperty(JsonWriter writer, Object value, JsonMemberMapping memberMapping)
at Newtonsoft.Json.JsonSerializer.SerializeObject(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
at HCD.Intranet.Core.Web.Mvc.NewtonsoftJsonResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
03/20/2009 01:41:59 10: Invalid attempt to call Read when reader is closed. System.InvalidOperationException[br] 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(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
at HCD.Intranet.Core.Data.Linq.LinqEmployeeRepository.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding, Int32 nonProjectId)
at HCD.Intranet.Core.Services.Impl.EmployeeService.CalculateHolidaysRemaining(Employee employee, DateTime weekEnding)
at HCD.Intranet.Core.Models.Timesheet.CalculateHolidaysRemaining()
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteTimesheet(JsonWriter writer, Timesheet timesheet)
at HCD.Intranet.Core.Models.Json.TimesheetJsonConverter.WriteJson(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.WriteMemberInfoProperty(JsonWriter writer, Object value, JsonMemberMapping memberMapping)
at Newtonsoft.Json.JsonSerializer.SerializeObject(JsonWriter writer, Object value)
at Newtonsoft.Json.JsonSerializer.SerializeValue(JsonWriter writer, Object value, JsonConverter memberConverter)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
at HCD.Intranet.Core.Web.Mvc.NewtonsoftJsonResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<InvokeActionResultWithFilters>b__e()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass11.<>c__DisplayClass13.<InvokeActionResultWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)