I am intermittently getting an System.InvalidCastException: Specified cast is not valid. error in my repository layer when performing an abstracted SELECT query mapped with LINQ.
The error can't be caused by a mismatched database schema since it works intermittently and it's on my local dev machine.
Could it be because StructureMap is caching the data context between page requests? If so, how do I tell StructureMap v2.6.1 to inject a new data context argument into my repository for each request?
Update: I found this question which correlates my hunch that something was being re-used. Looks like I need to call Dispose on my injected data context. Not sure how I'm going to do this to all my repositories without copypasting a lot of code.
Edit: These errors are popping up all over the place whenever I refresh my local machine too quickly. Doesn't look like it's happening on my remote deployment box, but I can't be sure.
I changed all my repositories' StructureMap life cycles to HttpContextScoped() and the error persists.
Code:
public ActionResult Index()
{
// error happens here, which queries my page repository
var page = _branchService.GetPage("welcome");
if (page != null)
ViewData["Welcome"] = page.Body;
...
}
Repository:
GetPage boils down to a filtered query mapping in my page repository.
public IQueryable<Page> GetPages()
{
var pages = from p in _db.Pages
let categories = GetPageCategories(p.PageId)
let revisions = GetRevisions(p.PageId)
select new Page
{
ID = p.PageId,
UserID = p.UserId,
Slug = p.Slug,
Title = p.Title,
Description = p.Description,
Body = p.Text,
Date = p.Date,
IsPublished = p.IsPublished,
Categories = new LazyList<Category>(categories),
Revisions = new LazyList<PageRevision>(revisions)
};
return pages;
}
where _db is an injected data context as an argument, stored in a private variable which I reuse for SELECT queries.
Error:
Specified cast is not valid.
Exception Details: System.InvalidCastException: Specified cast is not valid.
Stack Trace:
[InvalidCastException: Specified cast is not valid.]
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +4539
System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) +207
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +500
System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute(Expression expression) +50
System.Linq.Queryable.FirstOrDefault(IQueryable`1 source) +383
Manager.Controllers.SiteController.Index() in C:\Projects\Manager\Manager\Controllers\SiteController.cs:68
lambda_method(Closure , ControllerBase , Object[] ) +79
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +258
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
System.Web.Mvc.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() +125
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +709
System.Web.Mvc.Controller.ExecuteCore() +162
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +58
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371