C#MVC代码首先不返回所有字段

C#MVC代码首先不返回所有字段,c#,asp.net-mvc,asp.net-web-api2,C#,Asp.net Mvc,Asp.net Web Api2,我是MVC新手,在WebAPI2中使用代码优先的方法。这是我的模型: ChildModel.cs [DataContract(IsReference = true)] public class ChildModel { //other fields definition here //relationship definition [DataMember] public int ParentModelID {get; set;} [DataMember] p

我是MVC新手,在WebAPI2中使用代码优先的方法。这是我的模型:

ChildModel.cs

[DataContract(IsReference = true)]
public class ChildModel
{
   //other fields definition here

   //relationship definition
   [DataMember]
   public int ParentModelID {get; set;}
   [DataMember]
   public virtual ParentModel ParentModel {get; set;}
}
下面是我的控制器操作:

public IEnumerable<ChildModel> Get()
{
   return db.ChildModels.ToList();
}
它是这样交替的。第一个JSON是完整的,然后下一个只是$ref字段。这可能是什么原因造成的?我还注意到,当我在子模型中删除父模型的导航属性时,除了父模型没有在子模型的JSON中加载外,其他一切似乎都正常工作

希望有人能帮助我


谢谢

如果我没记错的话,EF使用延迟加载。 在调用list之前,请尝试向控制器操作添加
。包括(c=>c.ParentModel)


这应该告诉EF解析引用并提取完整对象。

首先,您不希望在任何地方加载父模型,因为查询中没有包含。当您尝试将数据库对象直接返回到API时,该API将尝试将它们序列化为Json或XML,从而对对象进行完整扫描

要解决您的问题,您可以这样做:

public IEnumerable<ChildModel> Get()
{
    db.Configuration.LazyLoadingEnabled = false;
    try
    {
        return db.ChildModels.Include("ParentModel").ToList();
    }
    finally
    {
        db.Configuration.LazyLoadingEnabled = true;
    }
}
…表示该对象引用Id 3中的另一个

考虑到您的Id为3的孩子与Id为1的孩子有相同的父母,则会发生以下情况:

  • 序列化子Id 1
  • 序列化子级
    ParentModel
    (访问它将触发延迟加载)
  • 序列化ParentModel(已延迟加载)
  • 序列化父模型的
    ChildModel
    集合(触发延迟加载)
  • ChildModel集合被延迟加载(包含两个子项,Id 1和3)
  • ref
    添加到子1(它以前已序列化)
  • 序列化子Id 3
  • 已完成父模型子序列化
  • 已完成父模型序列化
  • 已完成子Id 1序列化

  • 向子3添加一个
    ref
    (它以前是序列化的)

  • 序列化子Id 10
  • …继续序列化其他对象
这就是为什么我用
Include()
禁用了惰性加载和渴望加载的父模型


现在,这只是因为您试图将数据库对象直接返回到API。这就是为什么人们通常使用投影来返回DTO/ViewModel对象。

关闭延迟加载仍然不起作用。我仍然得到相同的输出。@Jed尝试删除
IsReference=true
,不再需要它了,尽管它应该可以使用,只要您只加载一次每个实体(因为正如我所说的,下一次它们将在json中显示为ref)。尝试删除它并告诉我它是否有效。@Allison否即使删除IsReference=true,它仍然是一样的。我还先删除了数据库,以确保它得到刷新。
public IEnumerable<ChildModel> Get()
{
    db.Configuration.LazyLoadingEnabled = false;
    try
    {
        return db.ChildModels.Include("ParentModel").ToList();
    }
    finally
    {
        db.Configuration.LazyLoadingEnabled = true;
    }
}
$ref: 3