2010-12-16 32 views
0

我遇到了一个情况,我的应用程序在Windows 7,64位上与特定数据集崩溃。所有其他平台在相同的数据集上工作良好。我已经确定我的应用崩溃了很多人发布的BuildNotContainsExpression。BuildNotContainsExpression导致System.StackOverflowException与Windows 7上的大数据集-64位

有没有一种方法可以使用堆内存来构建表达式?
我应该只是打破我的用户活动列表并处理较小的块(如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

+0

StackOverflow在问题名称中需要注释:) – 2010-12-16 17:20:45

+0

BuildNotContains是什么样子的?这听起来是递归的,但我想不出它是这样的一个原因。 – 2010-12-16 17:34:29

+0

另外,'WhereArray.Contains(a.Id)'不适用于EF吗?我期望它能够在LINQ到SQL中工作...... – 2010-12-16 17:37:01

回答

0

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

它看起来像你试图加入两张表来寻找缺失的Ids,但你所做的全是客户端而不是SQL服务器。

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

如果您的两张表格之间有FK关系,您可以使用简单的方式选择要删除的记录! .Any(...)子句。

+0

我正在使用Visual Studio 2008,我相信它是EF 3.5。我会看看你的例子。我是大自然的固件工程师,试图在我去的时候学习这个数据库的东西。到目前为止,我已经得到了一些工作,即使它们不是最高效的。 – ejwipp 2010-12-16 17:54:14

+0

你能否详细说明你最后的陈述?我查询的第一个表(在原始问题中显示为myTable)包含FK到usersSnapshot表。 – ejwipp 2010-12-16 20:29:02

+0

如果你有一个关联,可以像'myContext.myTableSnapshot.Where(ts =>!ts.myTable.Any())'一样简单。发布您的EDMX图将有所帮助。 EF从V1升级到V4。如果您不使用V4,我强烈建议您切换。 – 2010-12-16 23:40:58