Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a list of entities from a table leads to 500 error - Entity Framework

I'm building an SPA on Angular2 (front-end) and back-end web API 2 with OWIN and Identity for authentication and Ninject as a container for DI.

I want to return a list of Managers as json response. And also its related ContactDetail data. They are related as one-to-one in my database. But I'm getting a 500 error as response. Why am I getting this error?

Microsoft SQL Server Diagram

Manager class

   public partial class Manager
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ContactDetail ContactDetail { get; set; }
}

ContactDetail class

    public partial class ContactDetail
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string SecondName { get; set; }
    public string LastName { get; set; }

    public virtual Manager Manager { get; set; }
}

Context

 public partial class LightCRMEntities : DbContext
{
    public LightCRMEntities()
        : base("name=LightCRMEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<ContactDetail> ContactDetails { get; set; }
    public virtual DbSet<Manager> Managers { get; set; }
}

API controller

[Authorize(Roles = "Admin, Moderators")]

public class ManagerAPIController : ApiController
{
    private IManagerRepository _iManagerRepository;

    public ManagerAPIController(IManagerRepository iManagerRepository)
    {
        _iManagerRepository = iManagerRepository;
    }


    [HttpGet]
    [Route("api/AllManagers")]
    public IHttpActionResult GetAllManagers()
    {
        var managers = _iManagerRepository.Managers;
        return Json(managers);
    }
}

Repository:

 public class EFManagerRepository : IManagerRepository
{
    public IEnumerable<Manager> Managers
    {
        get
        {
            using (LightCRMEntities context = new LightCRMEntities())
            {
                return context.Managers.ToList();

            }
        }
    }

}

Error

  • ContactDetail '((System.Data.Entity.DynamicProxies.Manager_63305B0F1D8DAA0805603D889C6E3A5114E3050AEE610FE775000D2270697C1F)(new System.Collections.Generic.Mscorlib_CollectionDebugView(managers).Items[0])).ContactDetail' threw an exception of type 'System.ObjectDisposedException' LightCRM.ContactDetail {System.ObjectDisposedException}

Response:

I'm receiving 500 (Internal server error)

ExceptionMessage : "Error getting value from 'ContactDetail' on 'System.Data.Entity.DynamicProxies.Manager_63305B0F1D8DAA0805603D889C6E3A5114E3050AEE610FE775000D2270697C1F'." ExceptionType : "Newtonsoft.Json.JsonSerializationException"

Screenshot of a breakpoint: Though the error does not appear on this point - I can see that one of the related entities ContactDetail - has some problem to be loaded

breakpoint

I hardly understand the meaning of: Configuration.ProxyCreationEnabled = false; but if I add it to the constructor of the Context:

 public partial class LightCRMEntities : DbContext
{
    public LightCRMEntities()
        : base("name=LightCRMEntities")
    {
        Configuration.ProxyCreationEnabled = false;
    }
 // other code
}

Then I get 200 ok and a json object in console: json response

but it dosn't load the related object - it has a NULL value - ContactDetail : null

SQL profiler screenshot for this request:

SQL profiler

Screenshot of data in the database:

data in database

like image 508
Dmitriy Klyushin Avatar asked Nov 08 '22 04:11

Dmitriy Klyushin


1 Answers

Thanks to @JWeezy, @DavidG and other guys from the comment section of the original post the solution was found:

Modifications needed:

disable lazy loading in the Context

Context

public partial class LightCRMEntities : DbContext
{
    public LightCRMEntities()
        : base("name=LightCRMEntities")
    {
        Configuration.LazyLoadingEnabled = false;
    }
// other code
}

Used eager loading in the repository

public class EFManagerRepository : IManagerRepository
{
    public IEnumerable<Manager> Managers
    {
        get
        {
            using (LightCRMEntities context = new LightCRMEntities())
            {
                return context.Managers.Include("ContactDetail").ToList();

            }
        }
    }
}

In the ContactDetail class added [JsonIgnore] attribute to the virtual property

public partial class ContactDetail
{
   //other properties
    [JsonIgnore]
    public virtual Manager Manager { get; set; }
}
like image 72
Dmitriy Klyushin Avatar answered Nov 13 '22 22:11

Dmitriy Klyushin