Page 1 of 1

Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Thu Oct 16, 2025 12:50 pm
by avora@sherweb.com
Hello,

I'm licensed user and using Stimulsoft.Reports.Web.NetCore v2025.4.1. I need to apply the configured row limit when result is displated in View Data (new tab also) & Preview. My database has millions of records so when View Data is pressed, the app crashes. Even after applying lots of predicates for the query, there are millions of records. So anyhow limiting is required.

Below code works for Preview report (executes before StiNetCoreDesigner.PreviewReportResult from controller) but not for View Data (executes before StiNetCoreDesigner.DesignerEventResult from controller):

Code: Select all

 
           var stiSqlConnectionDatabase = (StiSqlDatabase)stiReport.Dictionary.Databases["Connection"];

            stiSqlConnectionDatabase.ConnectionString = _theService.GetConnectionString(userDetails);
            stiSqlConnectionDatabase.Connected += (_, _) =>
            {
                try
                {
                    var sqlConnection = (SqlConnection)stiReport.DataStore[0].Data;
                    sqlConnection.Open();

                    using var sqlCommand = sqlConnection.CreateCommand();
                    sqlCommand.CommandText = $"SET ROWCOUNT {_configurationService.GetOptions<StimulsoftOptions>(userDetails).SqlRowCount};";
                    sqlCommand.ExecuteNonQuery();
                }
                catch (Exception)
                {
                    // Ignore
                }
            };
The same code was working till version v2022.4.5. After upgrading to v2023.1.8 or till v2025.4.1, it doesn't. As per my detailed analysis, I have noticed from v2023.1.8 (https://www.stimulsoft.com/en/changes/r ... t/2023.1.8) there is change in SqlConnection. “The MS SQL Data Adapter System.Data.SqlClient has been replaced with a more functional Microsoft.Data.SqlClient for all .NET Standard 2.1 / .NET Core 3.1 / .NET 5 / .NET 6 components.” I believe this is true as when ran SQL Profiler:
- v2022.4.5: SPID is same for SET ROWCOUNT X; & for actual query, hence both executes in the same batch, Stimulsoft does not open new connection per queries. Works.
- v2023.1.8 till v2025.4.1: SPID is DIFFERENT for SET ROWCOUNT X; & for actual query, hence both executes in the same batch, Stimulsoft OPENS new connection per queries. DOES NOT WORK.

I have tried below approaches which DIDN'T WORK:
1. Updating SqlCommand by replacing SELECT with SELECT TOP: Just defaults data source query with SELECT TOP. When removed, does not apply row limit.
2. Tried RowNumer() > X filter on data source
3. Create custom data adapter
4. Updating SqlCommand for each data source on the report's dictionary by appending SET ROWCOUNT X;.
5. Creating a RowLimitConnectionWrapper & RowLimitCommandWrapper. It just defaults data source query in Designer with SET ROWCOUNT X; statement. When removed, does not apply row limit.
6. Creating custom function to limit the rows
7. Setting StiOptions.Engine.Data.MaxDataRowsForPreview
8. Setting MaxDataRowsOfDashboardElementInDesigner
9. report.Dictionary.DataSources.Items["YourDataSourceName"].MaxRows = maxRows;
10. stiReport.Dictionary.DataSources.ToList().ForEach(ds => ds.MaxDataRowsToProcess = 1000);- Not working as no such property

May I have some solution for this?

Thank you in Advance!

Re: Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Fri Oct 17, 2025 11:16 am
by Lech Kulikowski
Hello,

Could you please send a simple sample project? We’ll analyze it and try to find a solution for you.

Thank you.

Re: Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Fri Oct 17, 2025 3:30 pm
by avora@sherweb.com
I tried creating sample in your GitHub sample (NET 8.0 MVC Samples - https://github.com/stimulsoft/Samples-R ... /NET%208.0) but there is no SQL connection, so above code won't work there.

Creating a sample is too difficult for me and it will take very much time. If you can help me find solution without it, it's awesome. I have given lot of information that can help you dig more. However, I can explain little more.
When the `DesignerEvent` is called, I just attach the Connected event on (StiSqlDatabase)stiReport.Dictionary.Databases["Connection"] database connection, which in-turn executes the row-count query for MS Sql Server (v15.0.2145.1). After this, DesignerEvent endpoint returns the same report.
In this case, I have just opened a designer, expanded list of datasources (of SqlServer - created already), chosen one of the DS and hit Edit. It shows the default query (with SELECT TOP N) to that DS. When browse/view data clicked, it shows all the rows from that table into the new tab.
If I update query and remove TOP N, it fetches all the records.

Here are the screenshots of SQL Profiler: Hope this helps to identify the core problem!

Re: Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Mon Oct 20, 2025 9:03 am
by Evangeline
Before I proceed with creating a sample project, could you clarify if there are any specific configurations or settings within the Stimulsoft framework that might override the connection-level row count settings for the 'View Data' functionality? Additionally, have there been any updates or changes in the handling of SQL connections between versions that could impact the execution context of commands like SET ROWCOUNT?
Thank you!

Re: Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Tue Oct 21, 2025 6:38 am
by avora@sherweb.com
Hello,

Thank you for considering my request for sample project.

I don't think anything specific I have set. Please find below setup for Stimulsoft in my project. There are no major manipulations for the connection setup in the Stimulsoft framework. Also, there were no changes between version v2022.4.5 and v2023.1.8.

Options setup in Index.html:

Code: Select all

       @Html.Raw(
            Html.StiNetCoreDesigner(
                new StiNetCoreDesignerOptions
                {
                    Actions =
                    {
                        DesignerEvent = "DesignerEvent",
                        GetReport = "GetReport",
                        PreviewReport = "PreviewReport",
                        SaveReport = "SaveReport"
                    },
                    Behavior =
                    {
                        ShowSaveDialog = false
                    },
                    Dictionary =
                    {
                        ShowDictionaryContextMenuProperties = false,
                        PermissionDataConnections = StiDesignerPermissions.View
                    },
                    FileMenu =
                    {
                        ShowClose = false,
                        ShowNew = false,
                        ShowOpen = false,
                        ShowSaveAs = false
                    },
                    Localization = (string)ViewData["Localization"],
                    Server =
                    {
                        RequestTimeout = HtmlHelper.GetStimulsoftOptions().RequestTimeoutInSeconds // Default value is 30
                    }
                }))
Middleware for caching:

Code: Select all

public class StimulsoftFixMiddleware
{
    private readonly RequestDelegate _next;

    public StimulsoftFixMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/reportsdesigner"))
        {
            var originalStream = context.Response.Body;

            try
            {
                using (var memoryStream = new MemoryStream())
                {
                    context.Response.Body = memoryStream;
                    await _next(context);

                    memoryStream.Position = 0;
                    await memoryStream.CopyToAsync(originalStream);
                }
            }
            finally
            {
                context.Response.Body = originalStream;
            }

            return;
        }

        await _next(context);
    }
}

public static class StimulsoftFixMiddlewareExtensions
{
    public static IApplicationBuilder UseStimulsoftFix(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<StimulsoftFixMiddleware>();
    }
}

Report controller:

Code: Select all

        public IActionResult DesignerEvent()
        {
            var profile = GetUserProfile();

            var stiReport = StiNetCoreDesigner.GetReportObject(this);

            _reportsV2Service.ManageSqlConnection(stiReport, profile);

            return StiNetCoreDesigner.DesignerEventResult(this, stiReport);
        }

        public IActionResult GetReport(Guid id)
        {
            var profile = GetUserProfile();

            var report = _reportsV2Service.RetrieveDetails(id, profile);

            var stiReport = new StiReport();
            stiReport.LoadFromString(report.FileContent);

            _reportsV2Service.ManageSqlConnection(stiReport, profile);

            ClearConnectionString(stiReport);

            return StiNetCoreDesigner.GetReportResult(this, stiReport);
        }

        public IActionResult PreviewReport()
        {
            var profile = GetUserProfile();

            var stiReport = StiNetCoreDesigner.GetReportObject(this);

            _reportsV2Service.ManageSqlConnection(stiReport, profile);

            return StiNetCoreDesigner.PreviewReportResult(this, stiReport);
        }

        private static void ClearConnectionString(StiReport stiReport)
        {
            if (stiReport.Dictionary.Databases["Connection"] is not StiSqlDatabase defaultDatabaseConnection)
            {
                throw new InvalidCastException($"Couldn't convert database object to {nameof(StiSqlDatabase)}");
            }

            defaultDatabaseConnection.ConnectionString = "";
        }

ReportsV2Service:

Code: Select all

       …
        public void ManageSqlConnection(StiReport stiReport, UserProfile userProfile)
        {
            if (stiReport == null || stiReport.Dictionary.Databases.Count == 0)
            {
                return;
            }

            var stiSqlConnectionDatabase = (StiSqlDatabase)stiReport.Dictionary.Databases["Connection"];

            stiSqlConnectionDatabase.ConnectionString = GetConnectionString(userProfile);
            stiSqlConnectionDatabase.Connected += (_, _) =>
            {
                try
                {
                    var sqlConnection = (SqlConnection)stiReport.DataStore[0].Data;
                    sqlConnection.Open();

                    using var sqlCommand = sqlConnection.CreateCommand();
                    sqlCommand.CommandText = $"SET ROWCOUNT {_configService.GetOptions<StimulsoftOptions>(userProfile).SqlRowCount};"; // Default is 5000
                    sqlCommand.ExecuteNonQuery();
                }
                catch (Exception)
                {
                }
            };
        }
        …
I hope this will help you investigate further.

Also, may I request if this can be looked into on priority as it is blocker for our customers due to huge amount of data in their database?

Thank you

Re: Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Tue Oct 28, 2025 5:40 am
by avora@sherweb.com
Hello There,

Are you able to replicate the issue? Any update on the progress please?

As this is very urgent and crucial for our customers, we need resolution for this as earliest as possible.

Thank you

Re: Apply Row Count At Connection Level for 'View Data' & 'Preview' Report

Posted: Wed Oct 29, 2025 9:34 am
by Lech Kulikowski
Hello,

Unfortunately, the code provided was not sufficient; we were unable to reproduce the issue with our examples.
We need a sample project that we can run to reproduce the problem.

Thank you.