2014-09-06 51 views
0

我正在开发ASP.NET Web Api 2服务与.NET Framework 4.5.1和C#。伪递归调用= stackoverflow

我下面的这本书做到这一点: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 S和A Group具有User S作为Members

这两个班是我Data.Models和我使用的是Mapper类“翻译”他们作为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的成员,group1的成员是user1。所以,我得到这个:

  • CreateUseruser1它会调用CreateGroupgroup1
  • CreateGroup对于group1它将针对user1调用CreateUser
  • 等等...

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

的溶液可能是上User,或在MembersGroupCreateUserCreateGroup方法除去像Groups导航属性。

+0

刚刚创建空的用户和组,然后变异既包括在他们的收藏其他对象 - 这是OO /势在必行方式,而且是在这种情况下罚款 - 对一个不变的/功能性方法,你就需要[”打结“](http://www.haskell.org/haskellwiki/Tying_the_Knot) – Carsten 2014-09-06 10:03:44

+0

感谢您的评论,但如果我在克林贡读过它,我会理解相同的(是个玩笑,我不会说克林贡语:-))。我正在寻找更多关于打结的信息。谢谢。 – VansFannel 2014-09-06 10:06:50

+0

不,不,这确实有点像我这边的掠夺性评论 - 问题就在于,如果你想做这样的事情(相互递归定义某些事物而不改变),它会变得非常棘手 - 只需遵循我的第一条建议和创建用户和组,然后将它们添加到相互集合中;) – Carsten 2014-09-06 10:15:54

回答

2

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

  1. 简单图)两者的映射器的方法分成两个 - 第一个初始化简单的属性(姓名,ID),而第二个初始化导航属性。然后,在代码中调用映射器的地方,编写一段更长的脚本,以便使用这些新方法来初始化从用户到组的导航属性,但不需要调用其他方法(从组到用户)这样你就可以得到一个用户群组图形。

  2. 全图)一参数添加到您的每一个方法代表已经访问的对象的列表。然后,在递归调用后,检查元素是否已经在列表中,如果不是,则检查只有 - 将其添加并递归调用。这样,递归调用将探索用户和组之间的整个依赖关系图,并将确保没有用户和组不会被多次处理。