我遇到了一个情况,我的应用程序崩溃了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图表的适用部分:
答案 0 :(得分:0)
EF 4不需要BuildContainsExpression
,您使用的是早期版本吗?
看起来您正在尝试连接两个表来查找丢失的ID但是您在客户端而不是SQL服务器上执行此操作。
而是使用两个表之间的连接来查找没有相应用户的表快照。请参阅示例http://www.hookedonlinq.com/OuterJoinSample.ashx
如果您的两个表之间存在FK关系,则可以使用简单的方法选择要删除的记录! 。任何(...)条款。