【发布时间】:2017-09-13 11:08:37
【问题描述】:
写完这个问题并创建了一个 MCVE,这听起来有点像家庭作业,但实际上不是...... 不幸的是,我太老了,不能布置作业。
我正在尝试编写一个小应用程序来填充我正在使用的“金字塔”结构的数据库。 原会员1人,推荐10人。 这些推荐中的每一个都可以有 10 个推荐。每个人都有 10 个推荐人。等等……
我正在尝试用最大数量的成员(已提供)填充数据库
如果我将最大成员数设置为 100,000 - 这可行。 但是,200,000 会引发 StackOverflow 异常。
我很确定这取决于我没有足够早地终止“扇出”。但我终生无法弄清楚在哪里。
注意,为了简单起见,我下面的 MCVE 使用 Dapper,因此使用简单的 INSERT INTO 语句
public class MemberPopulator
{
private readonly SqlConnection connection;
private const string MemberSql = @"
INSERT INTO Members (FirstName, LastName, ReferralId, Active, Created)
VALUES (@FirstName, @LastName, @ReferralId, @Active, @Created);
SELECT CAST(SCOPE_IDENTITY() as int)";
private int TotalMemberCount;
private const int MaxMemberCount = 200000;
public MemberPopulator()
{
connection = new SqlConnection("Data Source=localhost;Initial Catalog=MyTestDb;Integrated Security=True");
}
public void CreateMembers()
{
//clear members
connection.Execute("TRUNCATE TABLE Members");
//create the 'original' member (top of pyramid)
var originalMemberId = connection.Query<int>(MemberSql, new Member
{
FirstName = "FirstName Goes Here",
ReferralId = 0
}).Single();
//now we have 1 total members
TotalMemberCount = 1;
//recursively create members, starting with original member,
RecursiveCreate(new[] { originalMemberId });
}
private void RecursiveCreate(IEnumerable<int> referralMemberIds)
{
//don't recurse if we've already got enough members
if (TotalMemberCount >= MaxMemberCount)
return;
foreach (var referralId in referralMemberIds)
{
//Create 10 members
var refs = CreateReferredMembers(referralId, 10);
RecursiveCreate(refs);
}
}
private IEnumerable<int> CreateReferredMembers(int referralId, int numberOfReferrals)
{
var referredMemberIds = new List<int>();
for (var i = 0; i < numberOfReferrals; i++)
{
if (TotalMemberCount >= MaxMemberCount)
break;
var member = new Member
{
FirstName = "FirstName Goes Here",
ReferralId = referralId
};
var memberId = connection.Query<int>(MemberSql, member).Single();
referredMemberIds.Add(memberId);
TotalMemberCount++;
}
return referredMemberIds;
}
}
【问题讨论】:
-
只有当你知道递归级别最小时,递归才是可行的。 20万已经很多了!请记住,递归很好,但总是可以用其他循环代替。从来没有必要。
-
^ 他说的。但是如果你坚持使用递归,你可以试试setting the stack size到更大的值。