C#MVC代码首先不返回所有字段
我是MVC新手,在WebAPI2中使用代码优先的方法。这是我的模型: ChildModel.csC#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
[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)
- 将
添加到子1(它以前已序列化)ref
- 序列化子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