开发者

BuildNotContainsExpression causes System.StackOverflowException with large data set on Windows 7 -64-bit

I have encountered a condition where my app crashes with a particular dataset on Windows 7, 64-bit. All other platforms work fine on the same dataset. I have determined that my app is crashing in the BuildNotContainsExpression that many people have posted.

Is there a way for the expression to be built using memory from the heap?

Should I just break done my usersActive list and process smaller chunks at a time (like 1000)?

Something else?

List<int> usersActive = myContext.myTable.Select(a => a.tableUsersSnapshot.id).Distinct().ToList();
// The code blows up (only on Win7 64-bit) on this line when usersActive is large ~4000
// (probably will blow up on all platforms if usersActive is sufficiently large)
expTest = CustomExpressions.BuildNotContainsExpression<tableUsersSnapshot, int>(a => a.id, usersActive);
List<tableUsersSnapshot> usersToDelete = myContext.myTableSnapshot.Where(expTest).ToList();
// Delete the objects in the delete list
foreach(tableUsersSnapshot user in usersToDelete)
{
    myContext.DeleteObject(user);
}

Edit: Here's the BuildNotContains function - it is not recursive:

public static Expression<Func<TElement, bool>> BuildNotContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
    {  
        if (null == valueSelector) { throw new ArgumentNullException("valueSelector");}
        if (null == values) { throw new ArgumentNullException("values"); }

        ParameterExpression p = valueSelector.Parameters.Single();

        // p => valueSelector(p) != values[0] && valueSelector(p) != ...

        if (!values.Any())
        {
            return e => true;
        }

        var equals = values.Select(value => (Expression)Expression.NotEqual(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
        var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.And(accumulate, eq开发者_如何学Pythonual));
        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }

Here's the applicable portion of my EDMX diagram:

BuildNotContainsExpression causes System.StackOverflowException with large data set on Windows 7 -64-bit


EF 4 doesn't require BuildContainsExpression, are you using an earlier version?

It looks like you are trying to join two tables to find missing Ids but you are doing it all client-side instead of on SQL server.

Instead, use a join between the two tables to find the table snapshots that don't have a corresponding user. See for example http://www.hookedonlinq.com/OuterJoinSample.ashx

If you had an FK relationship between your two tables you could select the records to delete using a simple ! .Any(...) clause.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜