Recovery Recovery - 3 months ago 17
C# Question

How can I get IQueryable as parameter in next method?

I'll try to make my code better and I dont know how to get IQueryable to next function

error:


An exception of type 'System.InvalidOperationException' occurred in
EntityFramework.dll but was not handled in user code

Additional information: The operation cannot be completed because the
DbContext has been disposed.


This is problem:

public List<GitUser> FavoritesUsersListFromHistory(IQueryable users)
{
List<GitUser> favoritesList = new List<GitUser>();
using (var db = new GitContext())
{
foreach (CookiesHistory result in users) <-- users make this error
{
var user = (from u in db.GitUsers
where u.Id == result.GitUserId
select new { u }).First();

favoritesList.Add(user.u);
}
}
return favoritesList;


This is code before change:

List<GitUser> favoritesList = new List<GitUser>();


using (var db = new GitContext())
{
var results = (from ch in db.CookiesHistory
where ch.GitUserId != null
where ch.MyCookieId == cookieId
group ch by new { ch.GitUserId, ch.MyCookieId, ch.SearchGitUser } into g
orderby g.Count() descending
select new { GitUserId = g.Key.GitUserId, MyCookieId = g.Key.MyCookieId, SearchGitUser = g.Key.SearchGitUser, Count = g.Count() }).Take(count);


foreach (var result in results)
{
var user = (from u in db.GitUsers
where u.Id == result.GitUserId
select new { u }).First();

favoritesList.Add(user.u);
}

return favoritesList;


This is code after change:

public FavoritesController(IGitUserRepository repo, CookieHelper _cookieHelper)
{
//myCookieRepository = cookieRepo;IMyCookieRepository cookieRepo,
repository = repo;
cookieHelper = _cookieHelper;
}




// GET: Favorites
public PartialViewResult FavoritesRepos()
{
IEnumerable<GitUser> favorites = FavoritesUsers(cookieHelper.GetHttpCookieId(), countOfFavoritesUsers);
return PartialView("_FavoritesRepos", favorites);
}



public IEnumerable<GitUser> FavoritesUsers(int cookieId, int count)
{
return FavoritesUsersListFromHistory(TopFavoritesUsers(cookieId, count));
}

public IQueryable TopFavoritesUsers(int cookieId, int count)
{
using (var db = new GitContext())
{
IQueryable results = (from ch in db.CookiesHistory
where ch.GitUserId != null
where ch.MyCookieId == cookieId
group ch by new { ch.GitUserId, ch.MyCookieId, ch.SearchGitUser } into g
orderby g.Count() descending
select new { GitUserId = g.Key.GitUserId, MyCookieId = g.Key.MyCookieId, SearchGitUser = g.Key.SearchGitUser, Count = g.Count() }).Take(count);
return results;
}
}

public List<GitUser> FavoritesUsersListFromHistory(IQueryable users)
{
List<GitUser> favoritesList = new List<GitUser>();
using (var db = new GitContext())
{
foreach (CookiesHistory result in users)
{
var user = (from u in db.GitUsers
where u.Id == result.GitUserId
select new { u }).First();

favoritesList.Add(user.u);
}
}
return favoritesList;
}

Answer

First thing is that error is due to the context you use to create the query you're passing as parameter has been disposed at the time you try to iterate over the result. So, my first recommendation is create your context variable as a global variable:

public class FavoriteController
{
   protected GitContext db;
   public FavoriteController()
   {
     db=new GitContext();
   }

  public IEnumerable<GitUser> FavoritesUsers(int cookieId, int count)
  {
        return FavoritesUsersListFromHistory(TopFavoritesUsers(cookieId, count));
  }

  //create a class (CookiesHistoryDTO) to save the result of this query
  public IQueryable<CookiesHistoryDTO> TopFavoritesUsers(int cookieId, int count)
  {

        IQueryable<CookiesHistoryDTO> results = (from ch in db.CookiesHistory
                                               where ch.GitUserId != null
                                               where ch.MyCookieId == cookieId
                                               group ch by new { ch.GitUserId, ch.MyCookieId, ch.SearchGitUser } into g
                                               orderby g.Count() descending
                                               select new CookiesHistoryDTO{ GitUserId = g.Key.GitUserId, MyCookieId = g.Key.MyCookieId, SearchGitUser = g.Key.SearchGitUser, Count = g.Count() }
                                              ).Take(count);
        return results;

  }


  public IEnumerable<GitUser> FavoritesUsersListFromHistory(IQueryable<CookiesHistoryDTO> user)
  {
     //Here the context you use to create your first query is still alive
     var userIds=user.Select(e=>e.GitUserId).Contains(e.Id);
     return db.GitUsers.Where(e=>userIds.Contains(e.Id)).ToList();// Here is when both query are going to be executed.
  }

  protected override void Dispose(bool disposing)
  {
    if (disposing)
    {
        db.Dispose();
    }
    base.Dispose(disposing);
  }
}
Comments