asp.net-mvc – 使用StructureMap / ASP.MVC / Visual Studio / LinqToSql的奇怪行为

我最近一直在使用带有StructureMap的新MVC框架并且总体上已经取得了很好的结果,但是,我一直遇到一个我无法理解的奇怪错误或者弄清楚如何解决.

这是我的架构:

> 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表达式构成 – ()=>由DSL注册表配置的新DBContext().

目前没有DBContext的缓存

在问题上:

我的索引页面加载并同时向ControllerOne和ControllerTwo发出两个Ajax请求,这些请求是通过MvcContrib的StructureMap控制器工厂构建的.

StructureMap注入了IService的具体类型,而IService又是使用配置的IRepository实例和新的DBContext对象创建的.

ControllerOne正在从IService实例请求一个模型,然后将其作为JsonActionResult返回,该模型由Newtonsoft.Json呈现.

ControllerTwo从IService实例请求一个不同的模型,当MVC框架执行ActionResult时,它也被序列化为Json对象.

我在VS2008中通过Cassini运行网站.

我偶尔会看到的问题是从LinqTosql生成错误

>数据无法读取,已有读者打开或
>无法将数据加载到数据表中,因为数据已存在(我目前没有确切的例外情况,但两者都是LinqTosql的内部).

如果ControllerOne中发生错误,则ControllerTwo也会因类似错误而失败,就好像这两个请求正在运行共享对象一样.

它不会一直出错,但它足以让我关注我的架构,并且它在某种程度上配置错误.

有没有什么方法可以在后续请求中返回ControllerOne和ControllerTwo的相同实例,或者它是否以任何方式缓存DBContext?即使我不是要求它?

在Visual Studio / Cassini中工作时有没有人见过类似的东西?通过IIS有帮助吗?

我应该删除LinqTosql吗?

关闭Visual Studio并再次打开通常可以解决问题一段时间.

非常感谢,如果有人能够解决这个问题.

编辑:包括来自NLog日志文件的日志片段(线程ID是半冒号前的数字):

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,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,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,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,JsonMemberMapping memberMapping)
   at Newtonsoft.Json.JsonSerializer.SerializeObject(JsonWriter writer,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,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,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,String actionName)
03/20/2009 01:41:59 12: controller=Timesheet,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,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,String actionName)

解决方法

我正在和Jeremy Miller讨论这个问题,你不想用SM来管理数据库上下文的生命周期 – 让repo根据需要进行实例化.这会带来如何进行对象更新/持久化的问题(如果您依赖于多个请求保持活动的上下文),但是不值得为Web应用程序依赖它.

我不得不从店面中删除db上下文管理的东西,原因是这样的 – 我得到了内存泄漏.我不会说这是SM的错 – 但总的来说只是让回购开启一个新的背景.

相关文章

这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识...
Some samples are below for ASP.Net web form controls:(fr...
问题描述: 对于未定义为 System.String 的列,唯一有效的值...
最近用到了CalendarExtender,结果不知道为什么发生了错位,...
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence cha...