I have a method that based on some parameters finds 'Transactions' between two dates given a list of strings. When the list is > 1000, I get a stack overflow exception trying to iterate on the list.
Here is my code
public List<string> CodesWithTransactionsBetweenDates(DateTime startInclusive, DateTime endExclusive, List<string> associatedCodes, int marketId)
{
List<string> codesWithTransactionsInPeriod = new List<string>();
using (var context = new MarketPlaceEntities())
{
var transactionList = (from transactions in context.Transactions
where
associatedCodes.Contains(transactions.User.Code) &&
transactions.MarketId == marketId &&
transactions.Date >= startInclusive &&
transactions.Date < endExclusive
group transactions by transactions.User.Code into uniqueIds
select new { UserCode = uniqueIds.Key });
foreach (var transaction in transactionList)
{
codesWithTransactionsInPeriod.Add(transaction.UserCode);
}
return codesWithTransactionsInPeriod;
}
}
Here is the stack trace... it goes past the point which visual studio can handle.
System.Data.Entity.dll!System.Data.Query.InternalTrees.BasicOpVisitor.VisitChildren(System.Data.Query.InternalTrees.Node n) + 0x3 bytes
System.Data.Entity.dll!System.Data.Query.PlanCompiler.GroupAggregateRefComputingVisitor.VisitDefault(System.Data.Query.InternalTrees.Node n) + 0x2b bytes
System.Data.Entity.dll!System.Data.Query.InternalTrees.BasicOpVisitor.VisitRelOpDefault(System.Data.Query.InternalTrees.RelOp op, System.Data.Query.InternalTrees.Node n) + 0xe bytes
System.Data.Entity.dll!System.Data.Query.InternalTrees.BasicOpVisitor.VisitApplyOp(System.Data.Query.InternalTrees.ApplyBaseOp op, System.Data.Query.InternalTrees.Node n) + 0xe bytes
System.Data.Entity.dll!System.Data.Query.InternalTrees.BasicOpVisitor.Visit(System.Data.Query.InternalTrees.OuterApplyOp op, System.Data.Query.InternalTrees.Node n) + 0xe bytes
System.Data.Entity.dll!System.Data.Query.InternalTrees.OuterApplyOp.Accept(System.Data.Query.InternalTrees.BasicOpVisitor v, System.Data.Query.InternalTrees.Node n) + 0x10 bytes
System.Data.Entity.dll!System.Data.Query.InternalTrees.BasicOpVisitor.VisitNode(System.Data.Query.InternalTrees.Node n) + 0x14 bytes
System.Data.Entity.dll!System.Data.Query.InternalTrees.BasicOpVisitor.VisitChildren(System.Data.Query.InternalTrees.Node n) + 0x60 bytes
My question is what is a way I can handle this query so that I do not have to worry about a stack overflow exception?
It seems like you're blowing the stack by iterating over the large collection, but also simultaneously add those objects to the list which results in two large, but basically identical collections. Instead just use AddRange for the list which accepts any IEnumerable.
List<string> codesWithTransactionsInPeriod = new List<string>();
using (var context = new MarketPlaceEntities())
{
return codesWithTransactionsInPeriod.AddRange((from transactions in context.Transactions
where
associatedCodes.Contains(transactions.User.Code) &&
transactions.MarketId == marketId &&
transactions.Date >= startInclusive &&
transactions.Date < endExclusive
group transactions by transactions.User.Code into uniqueIds
select uniqueIds.Key));
}
or without instantiating an empty list...
using (var context = new MarketPlaceEntities())
{
return (from transactions in context.Transactions
where
associatedCodes.Contains(transactions.User.Code) &&
transactions.MarketId == marketId &&
transactions.Date >= startInclusive &&
transactions.Date < endExclusive
group transactions by transactions.User.Code into uniqueIds
select uniqueIds.Key).ToList<string>();
}
or to preserve laziness... (Edited to use Lazy)
public Lazy<List<string>> LazyCodesWithTransactionsBetweenDates((DateTime startInclusive, DateTime endExclusive, List<string> associatedCodes, int marketId)
{
return new Lazy<List<string>>(CodesWithTransactionsBetweenDates(startInclusive, endExclusive, associatedCodes, marketId));
}
private List<string> CodesWithTransactionsBetweenDates(DateTime startInclusive, DateTime endExclusive, List<string> associatedCodes, int marketId)
{
using (var context = new MarketPlaceEntities())
{
return (from transactions in context.Transactions
where
associatedCodes.Contains(transactions.User.Code) &&
transactions.MarketId == marketId &&
transactions.Date >= startInclusive &&
transactions.Date < endExclusive
group transactions by transactions.User.Code into uniqueIds
select uniqueIds.Key).ToList<string>();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With