私のアプリケーションがWindows 7、64-bitの特定のデータセットでクラッシュするという条件が発生しました。他のすべてのプラットフォームは、同じデータセットで正常に動作します。私は多くの人々が投稿したBuildNotContainsExpressionで私のアプリがクラッシュしていると判断しました。BuildNotContainsExpressionにより、Windows 7 -64-bitで大きなデータセットが設定されたSystem.StackOverflowExceptionが発生する
ヒープのメモリを使用して式を構築する方法はありますか?
私は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図の該当部分です:
質問名でStackOverflowに必要なコメント:) –
BuildNotContainsはどのように見えますか?それは再帰的に聞こえるが、私はそれがそうである理由を考えることができない。 –
また、 'どこに!someArray.Contains(a.Id)'がEFで動作しないのですか?私はそれがLINQ-to-SQLで動作することを期待しています。 –