I am so curious, when I went to deep into Entity Framework and will be glad to help me understand about lazy loading in this example which I show here:

public partial class Customer
{
    public int CustomerID { get; set; }
    public Nullable<int> PersonID { get; set; }
    public Nullable<int> StoreID { get; set; }
    public Nullable<int> TerritoryID { get; set; }
    public string AccountNumber { get; set; }
    public System.DateTime ModifiedDate { get; set; }

    public virtual Territory Territory { get; set; }
}

public partial class Territory
{
    public Territory()
    {
        this.Customers = new HashSet<Customer>();
    }

    public int TerritoryID { get; set; }
    public string Name { get; set; }
    public string CountryRegionCode { get; set; }
    public string C_Group_ { get; set; }
    public decimal SalesYTD { get; set; }
    public decimal SalesLastYear { get; set; }

    public virtual ICollection<Customer> Customers { get; set; }
}


public ActionResult LoadData()
{
    var draw = Request.Form.GetValues("draw").FirstOrDefault();
    var start = Request.Form.GetValues("start").FirstOrDefault();
    var length = Request.Form.GetValues("length").FirstOrDefault();

    var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
    var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();

    var pageSize = length != null ? Convert.ToInt32(length) : 0;
    var skip = start != null ? Convert.ToInt32(start) : 0;
    int totalRecords = 0;

    using (MyDatabaseEntities dc = new MyDatabaseEntities())
    {           
        //1.
        var items = dc.Customers.Select(a => a);

        //2. 
        //var items = dc.Customers.Select(a => new
        //{
        //    a.CustomerID,
        //    a.PersonID,
        //    a.StoreID,
        //    TerritoryName = a.Territory.Name,
        //    a.AccountNumber,
        //    a.ModifiedDate
        //});

        if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
        {
            items = items.OrderBy(sortColumn + " " + sortColumnDir);
        }

        totalRecords = items.Count();
        var data = items.Skip(skip).Take(pageSize).ToList();

        return Json(new { recordsFiltered = totalRecords, recordsToral = totalRecords, data = data }, JsonRequestBehavior.AllowGet);
    }
}

I've numbered some parts. In first case as you see I select all customers, lazy loading is true and this throws an error:

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

If I uncomment the second part, it will work without errors. The only difference between them is that in second case I select columns which I need

share|improve this question
    
I would say that you don't need Select(a => a) in the first case. – Guru Stron Aug 31 '16 at 10:43
    
Also what is items.OrderBy here? OrderBy doesn't take a string as a parameter, it takes a func or more usually an expression. – DavidG Aug 31 '16 at 10:51
    
@DavidG I thought It would be understandable beacouse of I did not write whole code, I recorected it, you can check now – www1986 Aug 31 '16 at 11:07
up vote 2 down vote accepted

This is because JsonResult(from return Json(...) statement) will be executed by ASP after the using block is left and it will try to serialize all fields of your Customer object and will try to reach Territory reference property after your dbcontext has been disposed.

share|improve this answer
    
But in second case, I also make reference to Territory field in select statement and it works. Why? – www1986 Aug 31 '16 at 14:06
    
@www1986, yes, there is no laziness in second case, cause you fetch value TerritoryName = a.Territory.Name before leaving the using block. So in first case Territory is lazily evaluated during result execution after your action returns(and dbcontext is disposed), in second case dbcontext is not present during result execution, you have executed your request to database(items.Count() and items.Skip(skip).Take(pageSize).ToList()) and your are working with anonymous type, which has all the data already fetched. – Guru Stron Aug 31 '16 at 14:11
    
Thank you and I add that with eager loading would be the same error too, am I right? – www1986 Aug 31 '16 at 14:38
    
@www1986, no, if you add eager loading in first case (like items = dc.Customers.Include(a => a.Territory)) it should not fail, but if you will add something for lazy loading in the second case it will fail too(you can try to add something like Terr = a.Territory, to your select statement in second case, since Territory has navigation property Customers it should fail) – Guru Stron Aug 31 '16 at 14:56
1  
@www1986, no problem) Yes in first case it will return null for Territory without lazy loading cause it is not fetched from db in you query(you can use profiler to see what query is executed on your db), it will work if you add .Include(w => w.Territory). In second one you are explicitly tell that you need Territory in your select clause, so it is fetched from db. Here you can see a small explanation. – Guru Stron Sep 1 '16 at 12:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.