0

I am having an error on my web page:

{"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."}

It occours herein my view:

@model Service_Monitor_Web_Interface.Models.DashBoardViewModel
...    
=> @Html.DisplayFor(modelItem => item.Service.Name)

Here is my ViewModel class:

    public class DashBoardViewModel
{

    public int NumberOfUsers { get; set; }

    public virtual IEnumerable<ApplicationUser> recentUsers { get; set; }

    public virtual IEnumerable<UserActivityLog> logs { get; set; }

    public virtual IList<Service_Monitor_Domain.Entities.ServiceStatusHistory> serviceStatus { get; set; }

}

Here is my controller for the class:

   public ActionResult Index()
    {
        DashBoardViewModel vm = new DashBoardViewModel();  

        var dbs = new EFServiceStatusHistoryRepository();

        vm.serviceStatus = dbs.GetAllEnabledLatestStatusLog();

        return View(vm);
    }

and here is my function that access the db:

  public List<ServiceStatusHistory> GetAllEnabledLatestStatusLog()
    {
        List<ServiceStatusHistory> list = null;
        try
        {
            using (var db = new EFDbContext())
            {
                //var results = db.ServiceStatusHistory.Where(h => h.Service.Enabled)
                //                  .OrderByDescending(h => h.Id)
                //                  .GroupBy(h => h.Service.Id)
                //                  .Select(grp => grp.FirstOrDefault());

                var results = db.ServiceStatusHistory
                            .Where(x => x.Service.Enabled)
                            .GroupBy(x => x.Service)
                             .Select(x => x.OrderByDescending(y => y.time).FirstOrDefault());

                list = results.ToList();
            }
            return list;
        }
        catch
        {
            //Error
        }
        return list;
    }

Here is my entity:

    public class ServiceStatusHistory
{
    [Key]
    [Required]
    public int Id { get; set; }

    // Forenkey to service
    [Required]
    public virtual Service Service { get; set; }

    [Required]
    public ServiceStatus Status { get; set; }

    [Required]
    public string Messages { get; set; }

    [Required]
    //Time Logged in the db
    public DateTime time { get; set; }

    [Required]
    //Time the service last called the update method on the client
    public DateTime LastUpdateTime { get; set; }
 }

I think it has something to do with lazy loading. But I have not had this problem before when querying the same table? However it was just a simple select query.

0

2 Answers 2

2

Consider "Eager" loading of the Service class in your GetAllEnabledLatestStatusLog(). Be sure to include using System.Data.Entity
using System.Data.Entity var results = db.ServiceStatusHistory .Include("Service") .Where(x => x.Service.Enabled) .GroupBy(x => x.Service) .Select(x => x.OrderByDescending(y => y.time).FirstOrDefault()); See MSDN Loading Related Entities

Sign up to request clarification or add additional context in comments.

7 Comments

I think it is "Service", not "Services". Use strictly typed version of include to eliminate such kind of typo errors: .Include(x => x.Service).
@JimSTAT Please see my comment on the other answer as it is also relevant to your answer. Include is underlined red in visual studio.
@Zapnologica Be sure to include using System.Data.Entity
@JimSTAT, It now throws an error after executing the result: ` Unable to cast the type 'System.Linq.IQueryable1[[System.Linq.IGrouping2[[Service_Monitor_Domain.Entities.Service, Service Monitor Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Service_Monitor_Domain.Entities.ServiceStatusHistory, Service Monitor Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' to type ` to continue
I fixed it: Here is the query That worked: ` var result = db.ServiceStatusHistory .Include("Service") .Where(x => x.Service.Enabled) .GroupBy(x => x.Service) .Select(x => x.OrderByDescending(y => y.time).FirstOrDefault());`
|
0

I'd say that the problem here is that in your query you are not explicitly loading the related entities (in this case, ServiceStatusHistory.Service), presumably Lazy Loading is on by default.

So later on when you refer to item.Service.Name, the underlying EF class realises that it needs to load these related entities - except that the associated ObjectContext (in this case, EFDbContext) has long since been disposed.

So probably the simplest way to fix this is to modify your query to .Include() the related Service entities

 var results = db.ServiceStatusHistory
                    .Include("Service")
                    .Where(x => x.Service.Enabled)
                    .GroupBy(x => x.Service)

                    .Select(x => x.OrderByDescending(y => y.time).FirstOrDefault());

or you could turn off lazy loading for that query:

using (var db = new EFDbContext())
{
   db.Configuration.LazyLoadingEnabled=false;
   //use original query here
}

7 Comments

I changed my query and I am getting an error on the Include: System.Linq.IQueryable<System.Linq.IGrouping<Service_Monitor_Domain.Entities.Service,Service_Monitor_Domain.Entities.ServiceStatusHistory>>' does not contain a definition for 'Include' and no extension method 'Include' accepting a first argument of type 'System.Linq.IQueryable<System.Linq.IGrouping<Service_Monitor_Domain.Entities.Service,Service_Monitor_Domain.Entities.ServiceStatusHistory>>'
` db.ContextOptions.LazyLoadingEnabled = false;` also doesnt work. It says EFDbContext does not contain a defintion for contextOptions
@Zapnologica - yikes, my bad;see updated answer, it should work now. If not, ignore the second option anyway as the first is safer (since it won't eagerly load anything except what you tell it to)
Thanks, Regarding the turning off of lazy loading. my results where fairly odd. If i turned lazy loading off. my query would return a list of 4 items. and service would be valid for the first item and after that ie item 2 - 4 it was null ?
ok well in that case maybe it's better to use the include method then - as I previously mentioned it's probably better anyway because it gives you exact control over what to eagerly load.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.