Dispose Repository in html extensions

I have html extensions and am trying to use my repository list I have for select lists.   In my controllers I have the unit of work pattern and am disposing it properly with the dispose method but in the html extensions I need to know how to dispose my list repository.

I tried the following but when I get back to my view it says the context has been disposed.

I don't need to implement my uow in my html extensions because I only need my list repository.

        public static Kendo.Mvc.UI.Fluent.MultiSelectBuilder ClientAccountMultiSelectFor<TModel, TValue>(this HtmlHelper<TModel> html,
                Expression<Func<TModel, TValue>> expression, string id)
        {
            IQueryable<ClientAccountViewModel> clientAccounts = null;

            using (Entities entities = new Entities())
            {
                clientAccounts = new ListRepository(entities).GetClientAccountList("0", null, false).AsQueryable();

                return html.Kendo().MultiSelectFor(expression)
                    .Name(id)
                    .DataTextField("Text")
                    .DataValueField("Value")
                    .Filter("startswith")
                    .BindTo(new SelectList(clientAccounts, "ClientAccountID", "AccountName"));
            }
        }


I get the following error that I think I can resolve if I can dispose my repository and close the connection, I think I'm getting this error because I'm opening too many connections and not disposing them.

Error in "EntityFramework" application
Error Type: System.InvalidOperationException
Error Message: The underlying provider failed on Open.
LVL 2
michael1174Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
1) Are you talking about ListRepository?

2) Does ListRepository implement IDisposable?

3) What do you mean by "HTML Extensions"?
0
michael1174Author Commented:
#1 its just a regular repository pattern
#2 no
#3 asp.net mvc custom @html helper I wrote, I use it in my view like:
@Html.ClientAccountMultiSelectFor(m => m.ClientAccountIDSearch, "ClientAccountIDSearch")

In my html helper class, I also tried to have a static repository.  Even if I implement the IDisposable in that repository, the dispose method never executes.

 static ListRepository listRepository = new ListRepository(new Entities());
0
Bob LearnedCommented:
You need to call the Dispose method explicitly, through a call, or implicitly with a using block, or with this pattern:

IDisposable Done Right
https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/

For web sites, it is might be dangerous to use static variables, as there lifetime is different than you would expect with other platforms.

Static Variables and their implications in ASP.Net websites
http://blog.aggregatedintelligence.com/2009/01/static-variables-and-their-implications.html

Static variables should smell bad to you ALWAYS!
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

michael1174Author Commented:
ok, but how do I call dispose... as you can see below the list respository is called in the return of the control, where can I call dispose?

here is my html helper class

static ListRepository listRepository = new ListRepository(new Entities());

        public static Kendo.Mvc.UI.Fluent.MultiSelectBuilder ClientAccountMultiSelectFor<TModel, TValue>(this HtmlHelper<TModel> html,
                Expression<Func<TModel, TValue>> expression, string id)
        {
            return html.Kendo().MultiSelectFor(expression)
                    .Name(id)
                    .DataTextField("Text")
                    .DataValueField("Value")
                    .Filter("startswith")
                    .BindTo(new SelectList(listRepository.GetClientAccountList("0", null, false), "ClientAccountID", "AccountName")
                    );
        }
0
Bob LearnedCommented:
With a narrow view of the problem space that you are working with, would mean that it is difficult to see the correct place for the Dispose call.

Are you saying that you need to dispose of the entities that you pass in new ListRepository(new Entities())?  You can't dispose of anything that you don't have a reference to.
0
michael1174Author Commented:
There were 2 separate implementations.  I wasn't able to call dispose on either on.

The first post, I was getting a context already disposed while using the "Using" statement.  The last post I made was the 2nd implementation and I'm not sure where to call dispose since I'm returning the control and list repository call is embedded in controls bindto method.

I have my view:
@Html.ClientAccountMultiSelectFor(m => m.ClientAccountIDSearch, "ClientAccountIDSearch")


And I have my code either of those two methods is a class.

That's it.
0
Bob LearnedCommented:
"The first post, I was getting a context already disposed while using the "Using" statement."
You said that the Dispose method was not being called, so now I am confused.

What is disposing the context?  When does this error happen (i.e. after the 2nd call to the HTML helper method?
0
michael1174Author Commented:
The 1st implementation when I was using the "Using" statement I got the context already being dispose in my view.

This is my first attempt at disposing the context:

In my view:
@Html.ClientAccountMultiSelectFor(m => m.ClientAccountIDSearch, "ClientAccountIDSearch")

in my helper class:
public static Kendo.Mvc.UI.Fluent.MultiSelectBuilder ClientAccountMultiSelectFor<TModel, TValue>(this HtmlHelper<TModel> html,
                Expression<Func<TModel, TValue>> expression, string id)
        {
            IQueryable<ClientAccountViewModel> clientAccounts = null;

            using (Entities entities = new Entities())
            {
                clientAccounts = new ListRepository(entities).GetClientAccountList("0", null, false).AsQueryable();

                return html.Kendo().MultiSelectFor(expression)
                    .Name(id)
                    .DataTextField("Text")
                    .DataValueField("Value")
                    .Filter("startswith")
                    .BindTo(new SelectList(clientAccounts, "ClientAccountID", "AccountName"));
            }
        }



The 2nd implementation where I'm just calling a static list repository doesnt give me any errors but at the same time, I dont know how to call the dispose method. ListRepository implements IDisposable but its not being called after rendering the control in the view.

this is my 2nd attempt at trying to dispose, using different implementation:

my view still is the same:
@Html.ClientAccountMultiSelectFor(m => m.ClientAccountIDSearch, "ClientAccountIDSearch")

my helper class:
static ListRepository listRepository = new ListRepository(new Entities());

        public static Kendo.Mvc.UI.Fluent.MultiSelectBuilder ClientAccountMultiSelectFor<TModel, TValue>(this HtmlHelper<TModel> html,
                Expression<Func<TModel, TValue>> expression, string id)
        {
            return html.Kendo().MultiSelectFor(expression)
                    .Name(id)
                    .DataTextField("Text")
                    .DataValueField("Value")
                    .Filter("startswith")
                    .BindTo(new SelectList(listRepository.GetClientAccountList("0", null, false), "ClientAccountID", "AccountName")
                    );
        }

My ListRepository class does implement IDisposable with the dispose methods declared but they are not getting called after the control is rendered.

Hopefully its clearer now.  Thanks for any tips.
0
Bob LearnedCommented:
Are you using Entity Framework 6, or something older?

1) It doesn't make any sense in the first example, that you would get that exception, so there might be something else afoot.

2) I like to use a single instance of a data context, stored in a session variable, but I am not so certain that is a good pattern.

Reading this:

Managing DbContext the right way with Entity Framework 6: an in-depth guide
http://mehdi.me/ambient-dbcontext-in-ef6/
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
michael1174Author Commented:
I'm trying to stay away from session as much as I can, I dont mind having the lookup hit the db.

i am using EF 6.  In my controllers I have the uow implemented.  But since this html helper doesnt use the uow in my controllers, I can't properly dispose the context.  

I'll take another look at my first attempt  and look at your link, thanks.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.