繁体   English   中英

WebAPI响应导致“ System.OutOfMemoryException”

[英]WebAPI response causes “System.OutOfMemoryException”

我开发了一个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类。

看来您是直接从Web API(通过其内置的JSON序列化器)返回Entity Framework对象。 一般规则是永远不要这样做,因为JSON序列化程序将尝试序列化它可以找到的所有内容。 但是对于具有诸如您这样的关系的EF对象,它将不知道从何处停止,从而导致引用循环错误甚至内存不足错误。

相反,您需要准确地从EF对象中获取所需的或更确切地说:API调用程序所需的。

解决方案是创建对象/视图模型,以复制调用者需要的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之类的工具(一旦配置)来使结构更加结构化(一旦配置),它将在您需要的位置和时间进行映射。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM