C# 伪递归调用=堆栈溢出
我正在用.NET Framework 4.5.1和C#开发一个ASP.NET Web Api 2服务 我是按照这本书来做的: 我有这两门课 用户:C# 伪递归调用=堆栈溢出,c#,asp.net,asp.net-mvc,recursion,stack-overflow,C#,Asp.net,Asp.net Mvc,Recursion,Stack Overflow,我正在用.NET Framework 4.5.1和C#开发一个ASP.NET Web Api 2服务 我是按照这本书来做的: 我有这两门课 用户: public class User { public int UserId { get; set; } public string UserName { get; set; } public virtual ICollection<Group> Groups { get; set; } } public cla
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; }
}
正如您在Mapper
类中所看到的,CreateUser
方法调用CreateGroup
方法,以及CreateGroup
方法调用CreateUser
在我的例子中,user1
是group1
的成员,group1
拥有user1
作为成员。所以,我明白了:
- 在
上,对于CreateUser
它将为user1
调用group1
CreateGroup
- 在
上,对于CreateGroup
它将为group1
调用user1
CreateUser
- 等等
解决方案可以是从
CreateUser
和CreateGroup
方法中删除导航属性,如User
上的Groups
,或Groups
类中的成员
(simple graph)将两个映射器方法拆分为两个-第一个用于初始化简单属性(名称、id),第二个用于初始化导航属性。然后,在代码中调用映射器的地方,编写稍长一点的脚本,使用这些新方法初始化从用户到组的导航属性,但不要调用另一个方法(从组到用户),这样您将有一个指向组的用户图
(full graph)为每个方法添加一个尾部参数,该参数表示已访问对象的列表。然后,在递归调用时,检查元素是否已经在列表中,如果不在列表中,则只检查——添加它并递归调用。这样,递归调用将探索用户和组之间的整个依赖关系图,并确保不会多次处理任何用户和组
只需创建空用户和组,然后对两者进行变异,将另一个对象包含在它们的集合中——这是OO/命令式的方式,在本例中也很好——对于不可变/功能性的方法,您需要感谢您的评论,但如果我读过克林贡语,我也会理解相同的内容(这是一个笑话,我不会说克林贡语:-))。我正在搜索更多关于结婚的信息。谢谢。不,别这样-我这方面的评论确实有点站不住脚-问题是,如果你想做这样的事情(对某些东西的相互递归定义,而不进行变异),这真的很棘手-只需遵循我的第一个建议,创建用户和组,然后将它们添加到相互集合中;)你有一个循环,所以不要跟随已经处理过的用户/组。
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;
}