BuildNotContainsExpression导致System.StackOverflowException在Windows 7 -64位上设置大数据

时间:2010-12-16 17:17:32

标签: c# linq-to-entities stack-overflow

我遇到了一个情况,我的应用程序崩溃了Windows 7(64位)上的特定数据集。所有其他平台在同一数据集上运行良好。我已经确定我的应用程序在很多人发布的BuildNotContainsExpression中崩溃了。

是否有办法使用堆中的内存构建表达式?
我应该打破我的usersActive列表并一次处理较小的块(如1000)吗? 别的什么?

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);
}

编辑:这是BuildNotContains函数 - 它不是递归的:

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, equal));
        return Expression.Lambda<Func<TElement, bool>>(body, p);
    }

以下是我的EDMX图表的适用部分: alt text

1 个答案:

答案 0 :(得分:0)

EF 4不需要BuildContainsExpression,您使用的是早期版本吗?

看起来您正在尝试连接两个表来查找丢失的ID但是您在客户端而不是SQL服务器上执行此操作。

而是使用两个表之间的连接来查找没有相应用户的表快照。请参阅示例http://www.hookedonlinq.com/OuterJoinSample.ashx

如果您的两个表之间存在FK关系,则可以使用简单的方法选择要删除的记录! 。任何(...)条款。