从表中获取实体列表会导致500错误 - 实体框架

Dmi*_*hin 5 c# sql-server entity-framework

我正在Angular2(前端)和后端Web API 2上构建SPA,其中OWIN和Identity用于身份验证,Ninject用作DI的容器.

我想以json响应的形式返回Managers列表.还有它的相关ContactDetail数据.它们在我的数据库中一对一关联.但我收到500错误作为回应.为什么我收到此错误?

Microsoft SQL Server Diagram

经理班

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

    public virtual ContactDetail ContactDetail { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

ContactDetail类

    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; }
}
Run Code Online (Sandbox Code Playgroud)

上下文

 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; }
}
Run Code Online (Sandbox Code Playgroud)

API控制器

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

库:

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

            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

错误

  • ContactDetail'((System.Data.Entity.DynamicProxies.Manager_63305B0F1D8DAA0805603D889C6E3A5114E3050AEE610FE775000D2270697C1F)(new System.Collections.Generic.Mscorlib_CollectionDebugView(managers).Items [0])).ContactDetail'抛出类型为'System.ObjectDisposedException'的异常LightCRM.ContactDetail { System.ObjectDisposedException}

响应:

我收到500(内部服务器错误)

ExceptionMessage:"在'System.Data.Entity.DynamicProxies.Manager_63305B0F1D8DAA0805603D889C6E3A5114E3050AEE610FE775000D2270697C1F'上从'ContactDetail'获取值时出错." ExceptionType:"Newtonsoft.Json.JsonSerializationException"

断点的屏幕截图: 虽然此时没有出现错误 - 我可以看到其中一个相关实体ContactDetail - 有一些问题需要加载

断点

我几乎不明白其中的含义:Configuration.ProxyCreationEnabled = false;但如果我将它添加到Context的构造函数中:

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

然后我在控制台中得到200 ok和一个json对象: 杰森回应

但它不加载相关对象 - 它有一个NULL值 - ContactDetail:null

此请求的SQL profiler屏幕截图:

SQL分析器

数据库中数据的屏幕截图:

数据库中的数据

Dmi*_*hin 1

感谢@JWeezy、@DavidG 和原帖评论部分的其他人找到了解决方案:

需要修改:

禁用上下文中的延迟加载

语境

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

在存储库中使用了预加载

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

            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在ContactDetail类中为虚拟属性添加了[JsonIgnore]属性

public partial class ContactDetail
{
   //other properties
    [JsonIgnore]
    public virtual Manager Manager { get; set; }
}
Run Code Online (Sandbox Code Playgroud)