伪递归调用= stackoverflow

时间:2014-09-06 09:59:02

标签: c# asp.net asp.net-mvc recursion stack-overflow

我正在使用.NET Framework 4.5.1和C#开发ASP.NET Web Api 2服务。

我跟着这本书去做:ASP.NET MVC 4 and the Web API Building a REST Service from Start to Finish

我有这两个班。

用户

public class User
{
    public int UserId { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<Group> Groups { get; set; }
}

public class Group
{
    public int GroupId { get; set; }
    public string GroupName { get; set; }

    public ICollection<User> Members { get; set; }
}

User可以有Group个,GroupUserMembers

这两个班级是Data.Models,我使用Mapper班级来翻译&#39;使用这两种方法将它们作为Api.Models

public Models.User CreateUser(Data.Models.User modelUser)
{
    if (modelUser == null)
        return null;

    Models.User user = new Models.User()
    {
        UserId = modelUser.UserId,
        UserName = modelUser.UserName
    };

    if (modelUser.Groups != null)
        user.Groups = modelUser.Groups
            .Select(CreateGroup)
            .ToList();
}

public Models.Group CreateGroup(Data.Models.Group modelGroup)
{
    if (modelGroup == null)
        return null;

    Models.Group group = new Models.Group
    {
        GroupId = modelGroup.GroupId,
        GroupName = modelGroup.GroupName
    };

    if (modelGroup.Members != null)
        group.Members = modelGroup.Members
            .Select(CreateUser)
            .ToList();

    return group;
}

正如您在Mapper课程中所见,CreateUser方法调用CreateGroup方法和CreateGroup方法调用CreateUser

在我的情况下,user1group1的成员,group1user1成员。所以,我明白了:

  • CreateUser user1 CreateGroupgroup1CreateGroup
  • group1 CreateUser user1GroupsUser
  • 依旧......

关于如何避免这种无限递归调用的任何想法?

解决方案可能是从MembersGroup方法移除CreateUser上的CreateGroup或{{1}}类中的{{1}}等导航属性

1 个答案:

答案 0 :(得分:2)

至少有两种可能的解决方案(我可以想到两种,但可以有更多)。

  1. 简单图形)将您的mapper方法拆分为两个 - 第一个用于初始化简单属性(name,id),第二个用于初始化导航属性。然后,在代码中调用映射器的位置,编写一个稍长的脚本,使用这些新方法初始化用户到组的导航属性,但调用另一个方法(从组到用户),这样您就可以获得用户选择组的图表。

  2. 完整图表)为每个表示已访问过的对象列表的方法添加 tail 参数。然后,在递归调用时,检查元素是否已经在列表中,如果不是 - 添加它并递归调用。这样,递归调用将探索用户和组之间的整个依赖关系图,并确保不会多次处理任何用户和组。