在序列化具有一对多关系的实体时检测到循环引用

时间:2018-07-07 18:35:53

标签: asp.net json asp.net-mvc entity-framework

如何解决asp.net中的one to many关系问题?

我有Topic,其中包含许多playlists

我的代码:

public class Topic
{
    public int Id { get; set; }
    public String Name { get; set; }
    public String Image { get; set; }
    --->  public virtual List<Playlist> Playlist { get; set; }
}

public class Playlist
{
    public int Id { get; set; }
    public String Title { get; set; }
    public int TopicId { get; set; }
    ---> public virtual Topic Topic { get; set; }
}

我的控制器功能

[Route("data/binding/search")] 
public JsonResult Search()
{
    var search = Request["term"];
    var result=  from m in _context.Topics where m.Name.Contains(search) select m;
    return Json(result, JsonRequestBehavior.AllowGet);
}

当我调试代码时,我会看到无限的数据,因为Topics将调用playlist,然后playlist将调用Topics,最后一次调用Topic将会召回playlist等……!

通常,当我只是使用此关系来打印我的数据时,我没有看到任何错误,ASP.NET MVC 5可以解决该问题。

当我尝试将数据打印为Json时出现问题

enter image description here

有什么方法可以防止JSON中的无限数据循环吗?我只需要第一次数据,而不必一次又一次地调用引用

1 个答案:

答案 0 :(得分:3)

由于实体类具有循环属性引用,因此出现错误。

要解决此问题,您应该在LINQ查询中进行投影以仅获取所需的数据(Topic实体数据)。

这是将其投影到具有IdNameImage属性的匿名对象的方式。

public JsonResult Search(string term)
{
    var result = _context.Topics
                         .Where(a => a.Name.Contains(term))
                         .Select(x => new
                                          {
                                               Id = x.Id,
                                               Name = x.Name,
                                               Image = x.Image 
                                });
    return Json(result, JsonRequestBehavior.AllowGet);
}

如果您有一个表示主题实体数据的视图模型,则可以在投影部分中使用它而不是匿名对象

public class TopicVm
{
    public int Id { set;get;}
    public string Name { set;get;}
    public string Image { set;get;}
}
public JsonResult Search(string term)
{
    var result = _context.Topics
                         .Where(a => a.Name.Contains(term))
                         .Select(x => new TopicVm
                                          {
                                               Id = x.Id,
                                               Name = x.Name,
                                               Image = x.Image 
                                          });
    return Json(result, JsonRequestBehavior.AllowGet);
}

如果您还想包括“播放列表”属性数据,则可以在投影部分中完成。

public JsonResult Search(string term)
{
    var result = _context.Topics
                         .Where(a => a.Name.Contains(term))
                         .Select(x => new
                                          {
                                               Id = x.Id,
                                               Name = x.Name,
                                               Image = x.Image,
                                               Playlist = x.Playlist
                                                           .Select(p=>new
                                                            {
                                                              Id = p.Id,
                                                              Title = p.Title
                                                            })
                                });
    return Json(result, JsonRequestBehavior.AllowGet);
}