LINQ to SQL uses a query after a DataContext Dispose

I am writing a DLL for one project, I just started using LINQ to SQL and after moving all the methods to this new dll. I disabled that I cannot process the DataContext because it was configured, I understand why, but I'm not sure how I can satisfy the query results for my main project method, therefore:

My method in DLL

public static IEnumerable<Problem> GetProblemsNewest(int howMuch) { using (ProblemClassesDataContext context = new ProblemClassesDataContext()) { var problems = (from p in context.Problems orderby p.DateTimeCreated select p).Take(howMuch); return problems; } } 

Call:

 IEnumerable<Problem> problems = ProblemsManipulation.GetProblemsNewest(10); //Error can't acess it because it was disposed.. 

This is only the first method, I have great ones, so I really need a way to do this. Should there be a way to use LINQ to SQL in a DLL? I know that I can do something like .ToList or .ToArray , but then I could not directly use the properties of the string and would have to refer to it as a problem [0], problem [1], etc., What is even messier than having a code tone in the main project.

+2
source share
6 answers

Once you are outside the using statement, the context is automatically deleted, so when IEnumerable actually lists, the context is already located.

So you need to tell Linq that it should go ahead and actually retrieve the values ​​from the database when you are inside your using statement. You can do this via ToList() or ToArray (or others).

See updated code:

 public static IList<Problem> GetProblemsNewest(int howMuch) { using (ProblemClassesDataContext context = new ProblemClassesDataContext()) { var problems = (from p in context.Problems orderby p.DateTimeCreated select p).Take(howMuch); return problems.ToList(); } } 
+7
source

Change this:

 return problems; 

:

 return problems.ToList(); 

Explanation:

ToList () will iterate over the results and pull them all into memory. Since this happens inside a using statement, you're fine. And since it creates a list, your values ​​will be returned.

You could do it in other ways. The basic idea is to actually get the results before closing the using statement.

An alternative solution is to avoid using the using statement, create an iterator that owns the object and uses it when the last element was iterated.

+4
source

You can handle this by executing .ToList () in IEnumerable before exiting the use block. This will retrieve the entries and populate the list. Depending on your scenario, this may not be optimal in terms of performance (you lose the ability to lazy search and additional query filtering)

+1
source

You must complete the request inside the use clause, i.e. use ToList () or First () or Count (), etc.

+1
source

You are currently returning a request, and when you want to use it, since the database connection is closed before your use, you will get an exception, just do:

 return problems.AsEnumerable() 

This is due to canceled execution by the linq method. Actually, your problems object is just a request, and you have to convert it to objects in order to use it somewhere else.

+1
source

You may not want to use context when using; the problem is that later you won’t be able to use navigation properties because you will have the same problem with the object when it tries to load related data. What you need to do is let the context live and directly return the results. Or, when you return the results, call ToList() and then query for all related data.

0
source

Source: https://habr.com/ru/post/1488705/


All Articles