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.
Calling code:
public Page GetPage(string slug)
{
return _pageRepository.GetPages()
.WithSlug(slug).FirstOrDefault();
}
WithSlug is just a pipeline filter that adds a where clause to the query.
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
Messing around with disposing repositories didn't help, but setting MultipleActiveResultsets to true in my SQL connection string solved the problem.
Related
I am new to Sitecore,SoleNet. I have installed and configured Solr to work with Sitecore and I am able to see results.
I am now using code.
I added the connection string to UnityMVCActivator.cs in the Start()
Startup.Init("http://localhost:8983/solr/sitecore_web_index");
In my controller - Actionresults Index()
var solr = ServiceLocator.Current.GetInstance>();
I get this error
[InvalidOperationException: The type ISolrOperations1 does not have an
accessible constructor.]
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForNullExistingObject(IBuilderContext
context) +226 lambda_method(Closure , IBuilderContext ) +39
Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.b__0(IBuilderContext
context) +33
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext
context) +337
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext
context) +396 Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type
t, Object existing, String name, IEnumerable1 resolverOverrides) +238
[ResolutionFailedException: Resolution of the dependency failed, type
= "SolrNet.ISolrOperations`1[Niddk.Model.SearchResultsViewModel]", name = "(none)". Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type ISolrOperations`1 does not have an accessible constructor.
At the time of the exception, the container was:
Resolving
SolrNet.ISolrOperations1[Niddk.Model.SearchResultsViewModel],(none) ]
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object
existing, String name, IEnumerable1 resolverOverrides) +500
Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name,
ResolverOverride[] resolverOverrides) +20
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type
serviceType, String key) +55
[ActivationException: Activation error occured while trying to get
instance of type ISolrOperations1, key ""]
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type
serviceType, String key) +156
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance()
+62 Niddk.Web.Controllers.SearchController.Index() in C:\Users\ksivanandan\Source\Repos\web\Niddk\Niddk.Web\Controllers\SearchController.cs:23
lambda_method(Closure , ControllerBase , Object[] ) +87
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext
controllerContext, IDictionary2 parameters) +229
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor actionDescriptor, IDictionary2
parameters) +35
System.Web.Mvc.<>c__DisplayClass15.b__12()
+80 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext preContext, Func1 continuation) +453
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext preContext, Func`1 continuation) +453
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName) +533
My ViewModel
public class SearchResultsViewModel
{
[SolrField("headline_t")]
public string Headline { get; set; }
}
Any help is greatly appreciated.
Thank you!
Edit: this thread was also raised in GitHub in SolrNet and the project maintainer provided the right answer.
The problem is that for registering he is using the built in IoC but then resolving via Unity.
Original response
I may be reading your code wrong or something might be missing from the post but you are not passing the type:
In my controller - Actionresults Index()
var solr = ServiceLocator.Current.GetInstance<[you are missing this part]>();
When using generics you need to specify the type. I thinks this part would not even compile because of the .GetInstance>() being incomplete.
We have a weird situation going on here. We have setup a local installation of NuGet gallery (the same code that powers http://Nuget.org). The IIS and the DB are on the same box. The IIS App pool has been configured to run under a domain user who is the local admin on the box as well and has the "right to logon as a service" rights. Now when someone (after succesfully logging in) tries and upload a package, the upload package business takes ages and eventually throws up the "The underlying provider failed to open" error
[TimeoutException: Transaction Timeout]
[TransactionException: The operation is not valid for the state of the transaction.]
System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction) +53
System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification) +241
System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx) +273
System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction) +150
System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +2647
System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +89
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6372062
System.Data.SqlClient.SqlConnection.Open() +300
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +67
[EntityException: The underlying provider failed on Open.]
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +11109230
System.Data.EntityClient.EntityConnection.Open() +142
System.Data.Objects.ObjectContext.EnsureConnection() +97
System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal(String commandText, String entitySetName, MergeOption mergeOption, Object[] parameters) +109
System.Data.Objects.ObjectContext.ExecuteStoreQuery(String commandText, Object[] parameters) +87
System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(String sql, Object[] parameters) +118
System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable(String sql, Object[] parameters) +85
System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] parameters) +241
System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator() +34
System.Data.Entity.Internal.InternalSqlQuery`1.GetEnumerator() +28
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +382
System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
NuGetGallery.LuceneIndexingService.GetPackages(DbContext context, Nullable`1 dateTime) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Infrastructure\Lucene\LuceneIndexingService.cs:55
NuGetGallery.LuceneIndexingService.UpdateIndex() in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Infrastructure\Lucene\LuceneIndexingService.cs:32
NuGetGallery.PackageService.CreatePackage(IPackage nugetPackage, User currentUser) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Services\PackageService.cs:61
NuGetGallery.PackagesController.VerifyPackage(Nullable`1 listed) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Controllers\PackagesController.cs:503
lambda_method(Closure , ControllerBase , Object[] ) +121
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +248
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +125
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640
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) +691
System.Web.Mvc.Controller.ExecuteCore() +162
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +305
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375
Interestingly if I switch IIS App Pool to run under the built in "LocalSystem" account all these problems goes away. The domain user we want to use has been temporarily setup as the database owner for NuGetGallery database but it isn't helping.
Can anyone suggest what setting/configuration we might be missing here?
This was due to ambient transactions going on within the code. The code relied on TransactionScope classes to manage various transactions which were getting in a jam when they got nested. Things turned particularly bad if someone tried uploading a package which was more than around 10MB in size. Once we tweaked the MSDTC on the boxes the application started behaving slightly properly. However it was still intermittently getting deadlocked within its own transactions so for now we have decided to remove transactions from the package upload bit.
For anyone else who gets into this problem I would recommend either of these two
Comment out any reference to TransactionScope in
Services\PackageService.cs (method CreatePackage, line 48)
using (var tx = new TransactionScope())
{
using (var stream = nugetPackage.GetStream())
{
UpdateIsLatest(packageRegistration);
packageRegistrationRepo.CommitChanges();
packageFileSvc.SavePackageFile(package, stream);
tx.Complete();
}
}
And in Controller\PackageController.cs method VerifyPackage(bool? Listed) line 501
using (var tx = new TransactionScope())
{
package = packageSvc.CreatePackage(nugetPackage, currentUser);
packageSvc.PublishPackage(package.PackageRegistration.Id, package.Version);
if (listed.HasValue && listed.Value == false)
packageSvc.MarkPackageUnlisted(package);
uploadFileSvc.DeleteUploadFile(currentUser.Key);
tx.Complete();
}
2 Uncomment those lines and follow the approach mentioned here http://blogs.msdn.com/b/dbrowne/archive/2010/05/21/using-new-transactionscope-considered-harmful.aspx
Basically create a transactionscope which can work well with SQL Server. Create a new class in the InfraStructureFolder, call it TranscationUtils and copy the code in there. Then the using blocks would look like
using (var tx = new TransactionUtils.CreateTransactionScope()){
//cod here
tx.Complete();
}
However this second approach can result in another server error which again relates to the default time outs you can specify for TransactionScope. We have personally decided to go with approach 1 and comment out all TransactionScope references for now.
I'm trying to use mvcmailer in my mvc web app. When I used it in a dummy project and continued the steps stated in the wiki, it worked fine and I was able to send an email.
But when I tried to integrate it in my web app, its giving an error at "PopulateBody(mailMessage, viewName: "Welcome");" stating that it is unable to find _Layout.text. _Layout.text.cshtml and _Layout.cshtml exists in Usermailer folder along with Welcome.cshtml.
Usermailer code
public class UserMailer : MailerBase, IUserMailer
{
public UserMailer():
base()
{
MasterName="_Layout";
}
public virtual MailMessage Welcome(string email, string validationUrl)
{
var mailMessage = new MailMessage{Subject = "Welcome to GiftSocial"};
mailMessage.To.Add(email);
ViewBag.Validationkey = validationUrl;
PopulateBody(mailMessage, viewName: "Welcome");
return mailMessage;
}
}
Controller code
UserMailer.Welcome(email: model.Email, validationUrl: validationUrl).Send();
Copied exception Details:
System.Web.HttpException was unhandled by user code
Message=The layout page "_Layout.text" could not be found at the following path: "~/Views/UserMailer/_Layout.text".
Source=Mvc.Mailer
ErrorCode=-2147467259
WebEventCode=0
StackTrace:
at Mvc.Mailer.StringResult.ExecuteResult(ControllerContext context, String mailerName)
at Mvc.Mailer.MailerBase.EmailBody(String viewName, String masterName)
at Mvc.Mailer.MailerBase.PopulateTextBody(MailMessage mailMessage, String viewName, String masterName)
at Mvc.Mailer.MailerBase.PopulateBody(MailMessage mailMessage, String viewName, String masterName, Dictionary`2 linkedResources)
at MvcGiftSocial.Mailers.UserMailer.Welcome(String email, String validationUrl)
at MvcGiftSocial.Controllers.AccountController.Register(RegisterViewModel viewmodel, String returnUrl) in C:\Users\ASUS\Documents\Visual Studio 2010\Projects\GiftSocialAzureNew\MvcGiftSocial\Controllers\AccountController.cs:line 86
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
InnerException:
I would sincerely appreciate if someone could tell me what I'm doing wrong..
Thanks
Arnab
The error is pretty much self-explanatory. The required views were not found.
It seems that you were trying to send text/plain mail message. Therefor MvcMailer was looking for such views.
See: https://github.com/smsohan/MvcMailer/wiki/MvcMailer-Step-by-Step-Guide#wiki-send-multi-part-emails
I am trying to load data of a user edit it and then save it. this has been working and im not quite sure what i changed but now i am getting the following error...
Value cannot be null.
Parameter name: value
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: value
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ArgumentNullException: Value cannot be null.
Parameter name: value]
System.ComponentModel.DataAnnotations.ValidationContext.set_DisplayName(String value) +51903
System.Web.Mvc.<Validate>d__1.MoveNext() +135
System.Web.Mvc.<Validate>d__5.MoveNext() +318
System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +139
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +66
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1367
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +449
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8897857
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
public ActionResult EditDetails()
{
int id = Convert.ToInt32(Session["user"]);
S1_Customers u1_users = storeDB.S1_Customers.Find(id);
return View(u1_users);
}
[HttpPost]
public ActionResult EditDetails(S1_Customers u1_users)
{
var Pcode = "";
if (ModelState.IsValid)
{
I am not even reaching ModelState.IsValid when i click submit
Did you change any names? The form names have to map 1-1 with your Action parameters. In this case, the "name" parameter was not passed to the controller action, so it is null.
Wild guess, need more information (method signature of action)
You'll receive that error if you have some properties decorated by DisplayAttribute with empty Name
([DisplayAttribute(Name = "", Description = "Any description")])
If you use [Display(Name="")] as for properties of your model, This will cause the error you get. To solve this problem, you should avoid using empty display name attribute.
[Display(Name = "")] //this line is the cause of error
public string PromotionCode { get; set; }
It could most probably be that your model has a property that returns a non-nullable value, like int, DateTime, double etc. And if user is updating the entry you are probably not storing that value in a hidden field or somewhere, so when the data is returned that particular property is null. Either place that property into a hidden field or make your property nullable in a model by changing int to int?, etc.
I was getting this same error message when manually setting a #Html.TextArea, I had used the code from an #Html.TextBox(null, this.Model) in an EditorTemplate and when I did #Html.TextArea(null, this.Model) I got the error above.
Turns out you have to do #Html.TextArea("", this.Model) and it works.
I'm using StructureMap to inject a LINQ data context (DB class) into my repositories for read queries on a HTTP-context basis, which are queried via a service layer. Everything works fine for a few hours until I get a "Broken" Connection ExecuteReader error (see below for full dump).
Write queries (not read queries) are wrapped in a using (var db = new DB()) {...} statement, which I don't think cause the problem.
I've added MultipleActiveResultSets=true; to my connection string, which seemed to solve the problem for a while, but the error returns until I recycle my application pool, which temporarily solves the problem. Presumably recycling the pool frees all the "broken" data contexes.
StructureMap is configured to inject a data context and repository for each HTTP context:
For<DB>().HttpContextScoped().Use(new DB());
For<IUserRepository>().HttpContextScoped().Use<SqlUserRepository>();
The data context is consumed by my user repository like so:
private DB _db;
public SqlUserRepository(DB db)
{
_db = db;
}
which, in turn conveniently queries the data context like so:
public IQueryable<User> GetUsers()
{
var users = from u in _db.Users
select u; // omitted the rest
}
Which after a few hours ends up with this horrible error:
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)
How do I solve this? I really don't want to have to manually wrap every query in a using-statement.
It looks like you're unintentionally are creating a singleton of the Context:
For<DB>().HttpContextScoped().Use(new DB());
In order to create a new context per request, use this instead:
For<DB>().HttpContextScoped().Use(() => new DB());
I would just use a new DataContext for each repository unless you can't for some reason. See this question: Strange behaviour with StructureMap / ASP.MVC / Visual Studio / LinqToSql
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.
One reason for this would be that your connection could not be opening at all. What ever exception that is coming at the "SqlConnection.Open" statement is being suppressed. If the problem is not in your application it could be that server is unable to grant you a connection. Could be because of a connection leak in your app or in some other database hosted on the same server.