C# 在数据库查询中使用.Include()会创建无限的数据循环

C# 在数据库查询中使用.Include()会创建无限的数据循环,c#,asp.net,linq,.net-core,entity-framework-core,C#,Asp.net,Linq,.net Core,Entity Framework Core,问题:我使用LINQ查询关系数据库的实体框架上下文。接下来,我创建了一个包含一些关系的数据库,但是当我使用ASP.NET将数据发送到服务器时,这些关系的值为空 通过进一步挖掘,我发现我需要使用\u context.Post.Include(“Blog”)来发送数据,因为它使用延迟加载。然而,通过这样做,它在JsonResult中创建了一个“无限循环” 最终返回的数据似乎被一分为二,加载时会出现JSON解析错误,因为它缺少JSON数据的后半部分 示例返回值 {"id": 0, "blogId":

问题:我使用LINQ查询关系数据库的实体框架上下文。接下来,我创建了一个包含一些关系的数据库,但是当我使用ASP.NET将数据发送到服务器时,这些关系的值为空

通过进一步挖掘,我发现我需要使用
\u context.Post.Include(“Blog”)
来发送数据,因为它使用延迟加载。然而,通过这样做,它在JsonResult中创建了一个“无限循环”

最终返回的数据似乎被一分为二,加载时会出现JSON解析错误,因为它缺少JSON数据的后半部分

示例返回值

{"id": 0, "blogId": 1, "blog": {"postId":0

这就是它返回的所有内容,因为在该帖子之后的任何内容都将是对原始帖子的引用,而原始帖子反过来又有对博客的引用。是否有任何方法可以使用LINQ在返回中排除post对象,类似于最初包含博客的方式?

这是JSON序列化问题。 搜索如何解决JSON流序列化程序文档中的“循环引用”问题。 不同的流序列化程序提供不同的解决方案:

  • 配置最大深度
  • 基于引用缓存的历史记录
  • 将特定类型序列化程序配置为不使用“导航属性”
  • 其他解决方案-不使用流序列化程序-就地配置序列化程序功能

    另一种方法是使用DTO类(其中没有循环引用)


    您还可以尝试分离实体,并将要忽略的每个导航属性设置为null,但这很难看,不推荐使用

    修正了!我获取了来自包含关系的数据库的模型,然后使用foreach来消除反向引用

    var blog = await _context.Blog
        .Include(x => x.Posts)
        .SingleAsync(x => x.Id == id);
    
    foreach (Post post in blog.Posts)
    {
        post.Blog = null;
    }
    return Ok(blog);
    

    你需要提供更多关于数据库表以及它们之间关系的详细信息。我自己并没有做任何序列化,而是由ASP在返回ActionResult时完成的。它只是放弃,然后返回到放弃之前的点,不费心修改标记。我知道。但是你应该。选择一个:全局配置JSON序列化程序以处理循环引用、自行序列化数据或将实体转换为DTO。它使用的是脚手架API控制器,我可以想象这是一种“正确”的方法。1)脚手架只是一个非常基本的工具。realcontroller中应该缺少的很多东西(日志记录、遥测、SQLServer消息解析、rowversion支持、多对多支持等)。2) “循环引用”是一个基本的序列化问题。没有一个程序员可以避免它。我只是不明白为什么循环引用会存在。文档中说,如果我想包含一个级别,我需要包含它,因为它不会自动发送,但它似乎只是神奇地发送。这很有效,但在处理大量复杂类时,它的扩展性不好。我以前尝试过在这个问题上使用反射,结果它变得一团糟。更不用说额外的处理会影响性能。