how to filter linq expression for use with CodeSmith bulk update

836 Views Asked by At

I'm using CodeSmith Plinqo's bulk update functionality with the following wrapper code:

public int Update<TEntity>(Expression<Func<TEntity, bool>> filter, 
    Expression<Func<TEntity, TEntity>> evaluator) where TEntity : class
{
    var tbl = _dataContext.GetTable<TEntity>();
    return tbl.Update(filter, evaluator);
}

Example Usage:

DCCore.Update<Code>(filter => _results.UpdatedCodes.Select(
    x => x.CodeID).Contains(filter.CodeID),
    u => new Code {
        CodeStatusID = EpcEvent.CodeStatusID.Value
    });

This works great except when the "filter" contains more than 2100 elements, then we get the sql server error: "The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Too many parameters were provided in this RPC request. The maximum is 2100."

What I'd like to do is enhance my Update wrapper so that it breaks the "filter" expression into 2000 item chunks. Something like this pseudo code:

public int Update<TEntity>(Expression<Func<TEntity, bool>> filter, 
    Expression<Func<TEntity, TEntity>> evaluator) where TEntity : class
{
    var tbl = _dataContext.GetTable<TEntity>();
    var index = 0;
    const int chunk = 2000;
    var filterCount = filter.Count();
    while (index * chunk < filterCount)
    {
        var smallFilter = filter.Skip(index*chunk).Take(chunk);
        tbl.Update(smallFilter, evaluator);
        index++;
    }
    return filterCount;
}
1

There are 1 best solutions below

1
On

I work for CodeSmith Tools. There was a user on our forum earlier this year who posted this issue: http://community.codesmithtools.com/Template_Frameworks/f/66/t/12717.aspx I still think the best route would be to use a stored procedure. However, his fix was similar to yours.