我开发了一个WebAPI服务,它在响应中返回一组复杂的自定义对象。 他们的一些领域有多对多的关系。例如:
[Table("OEReferences", Schema = "public")]
public class OEReference
{
[NotMapped]
public IList<IAReference> IAReferences{ get; set; }
}
[Table("IAReferences", Schema = "public")]
public class IAReference
{
[NotMapped]
public IList<OEReference> OEReferences{ get; set; }
}
每个OEReference对象都有一个IAReferences列表,同时每个IAReference对象都有一个OEReference列表(包括第一个)及其对应的IAReferences列表等等。它永远不会停止。
有时我会遇到内存不足异常。这是什么原因?我该怎样预防呢?
只有约50个OEReference,它们每个都包含几个IAReferences。其余的领域非常简单。 我在.Net 4.7.1中使用HttpClient类。
答案 0 :(得分:1)
看起来您正在直接从Web API返回Entity Framework对象(通过其内置的JSON Serializer)。一般规则是永远不要这样做,因为JSON Serializer将尝试序列化它能找到的所有东西。但是如果EF对象具有你的关系,它就不会知道停止的位置,导致参考循环错误甚至内存不足错误。
相反,您需要从EF对象中获取所需内容,或者更准确地说:您的API调用者需要什么。
解决方案是创建Objects / ViewModels,它复制调用者需要的EF对象部分,填充EF对象中的部分,然后返回它们。
快速而肮脏的方法是使用匿名对象,例如:
// Instead of "return EF_Item":
return new
{
Item = new
{
Id = EF_Item.Id,
Description = EF_Item.Description,
Things = MapThings(EF_Item.Things) // helper function that you need to provide
}
};
一个好的经验法则是只将EF对象中的简单属性(数字,布尔值,字符串,日期时间)分配给ViewModel项。一旦遇到另一个EF对象(或EF对象集合)的EF对象属性,您就需要将这些属性转换为未链接到EF的“简单”对象。
更结构化的方法是使用ViewModel类,您可以使用AutoMapper之类的工具使其更加结构化(一旦配置)将随时随地为您进行映射。