【问题标题】:WebAPI response causes "System.OutOfMemoryException"WebAPI 响应导致“System.OutOfMemoryException”
【发布时间】:2017-12-20 16:27:53
【问题描述】:

我开发了一个 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,每个都包含几个 IARreference,这简直是破坏性的。其余字段非常简单。 我在 .Net 4.7.1 中使用 HttpClient 类。

【问题讨论】:

    标签: c# asp.net-web-api out-of-memory


    【解决方案1】:

    看起来您是直接从 Web API 返回实体框架对象(通过其内置的 JSON 序列化器)。一般规则是永远不要这样做,因为 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 等工具使之更加结构化,该工具(一旦配置)将随时随地为您进行映射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多