Blog Post

Microsoft Giveth and Taketh, the mystery of the SPAuditQuery.RowLimit property

Clavin Fernandes
Illustration: Microsoft Giveth and Taketh, the mystery of the SPAuditQuery.RowLimit property

During a recent optimisation cycle of our Audit Log Viewer (Part of the Muhimbi SharePoint Audit Suite) we noticed the RowLimit property on the SPAuditQuery object. Weird, not sure why we missed this the first time around, but we’ll gladly accept this gift and move on.

The thing is, some of our customers just blindly enable all audit events on all of their site collections and never look back. The record stands, I kid you not, at 848 Million lines of audit data in a single table. As our audit software behaves like a good SharePoint citizen, we access all data through the SharePoint object model and never touch the database directly.

Unfortunately, if a user queries the audit log and removes all filters, the SharePoint object model retrieves all data and happily converts each and every line of audit data into an SPAuditEntry object. This is a relatively slow process that cannot be interrupted and may result in extreme memory and cpu usage.

OK, so back to this shiny RowLimit property. Our log viewer already contained some optimisations to deal with large amounts of data, but being able to set the RowLimit is going to solve the problems of even our most demanding customers….. excellent.

Excellent indeed, everything was working great in our development environment, but during a regression test one of our Test farms was complaining and threw an Exception related to get_RowLimit() not being found…. bugger! We rubbed our eyes, fired up Reflector and compared Microsoft.SharePoint.dll from our Test environment with the one in our Development environment.

RowLimit

As is evident in the screenshot listed above, the version running in our Development environment (on the right) has public members that are not present in the version running in our Test Environment (on the left).

It appears that Microsoft has not documented on which version of the DLL the RowLimit property was introduced (12.0.6219.1000 doesn’t have it, but 12.0.6318.5000 does) so we have decided to detect the availability of the property at runtime to allow our software to auto optimise on systems running the newer version of the DLL.

The code is split up in two methods as the actual line using the RowLimit property cannot be in the same method that is testing its presence. This is related to how .net’s JIT compiler works in the background.

/// <summary>
/// Check presence of RowLimit and set the value
/// </summary>
/// <param name="wssQuery">The query to set the limit on.</param>
public static void SetRowLimit(SPAuditQuery wssQuery)
{
    Type t = typeof(Microsoft.SharePoint.SPAuditQuery);
    PropertyInfo p = t.GetProperty("RowLimit");
    if (p != null)
    {
        SetRowLimitInternal(wssQuery);
    }
}
/// <summary>
/// Internal method for setting the actual row limit. In its own method
/// to prevent the JIT from tripping over in the SetRowLimit method above.
/// </summary>
/// <param name="wssQuery">The query to set the limit on.</param>
private static void SetRowLimitInternal(SPAuditQuery wssQuery)
{
    wssQuery.RowLimit = MAX_QUERY_ROWS;
}
Author
Clavin Fernandes Developer Relations and Support Services

Clavin is a Microsoft Business Applications MVP who supports 1,000+ high-level enterprise customers with challenges related to PDF conversion in combination with SharePoint on-premises Office 365, Azure, Nintex, K2, and Power Platform mostly no-code solutions.

Explore related topics

Share post
Free trial Ready to get started?
Free trial