예제 #1
0
        public async Task <ReportOutput> ExecuteReportOutputAsync(ReportDefinition reportDefinition, IDictionary <string, string> values)
        {
            ReportCommandContext context = new ReportCommandContext(reportDefinition, reportDefinition.Output.Command);

            if (!string.IsNullOrWhiteSpace(reportDefinition.ContextProvider))
            {
                Type contextProviderType = Type.GetType(reportDefinition.ContextProvider, true, true);
                context.ContextProvider = ActivatorUtilities.CreateInstance(this.ServiceProvider, contextProviderType);
            }

            var reportCommand = await this.CommandBuilder.BuildCommandAsync(context, values);

            using (IServiceScope serviceScope = this.ServiceProvider.GetRequiredService <IServiceScopeFactory>().CreateScope())
            {
                if (!reportDefinition.TryFindDataSourceDefinition(reportDefinition.Output, out DataSourceDefinition dataSourceDefinition))
                {
                    throw new InvalidOperationException($"Could not find data source definition '{reportDefinition.Output.DataSource}' in the report '{reportDefinition.Name}'.");
                }

                var dataSourceRegistrationOptionsSnapshot = serviceScope.ServiceProvider.GetRequiredService <IOptionsSnapshot <DataSourceRegistrationOptions> >();
                var dataSourceRegistrationOptions         = dataSourceRegistrationOptionsSnapshot.Get(dataSourceDefinition.Type);

                if (null == dataSourceRegistrationOptions.TypeHandle || IntPtr.Zero == dataSourceRegistrationOptions.TypeHandle.Value)
                {
                    throw new InvalidOperationException($"No data source service is registered for data source type '{dataSourceDefinition.Type}'.");
                }

                Type        dataSourceType = Type.GetTypeFromHandle(dataSourceRegistrationOptions.TypeHandle);
                IDataSource dataSource     = (IDataSource)serviceScope.ServiceProvider.GetRequiredService(dataSourceType);
                await dataSource.OpenAsync(dataSourceDefinition);

                try
                {
                    var dataset = await dataSource.GetDataAsync(reportCommand, reportDefinition.EnumerateFieldDefinitions().ToArray());

                    return(new ReportOutput(reportCommand, dataset));
                }
                finally
                {
                    await dataSource.CloseAsync();
                }
            }
        }
예제 #2
0
        public async Task <ReportCommand> BuildCommandAsync(ReportCommandContext context, IDictionary <string, string> values)
        {
            if (!this.TryParseCommandText(context.CommandDefinition.CommandText, out string commandText, out IList <string> parameterNames))
            {
                throw new InvalidOperationException($"Failed to parse command '{context.CommandName}' in report '{context.ReportDefinition.Name}'.");
            }

            ReportCommand reportCommand = new ReportCommand(commandText, context.CommandDefinition);

            if (null == values)
            {
                values = new Dictionary <string, string>(new FilterNameComparer());
            }
            else
            {
                values = new Dictionary <string, string>(values, new FilterNameComparer());
            }

            foreach (string parameterName in parameterNames)
            {
                if (context.ReportDefinition.TryFindFilterDefinition(parameterName, out FilterDefinition filterDefinition))
                {
                    if (!values.TryGetValue(parameterName, out string rawValue))
                    {
                        rawValue = null;
                    }

                    FilterValue filterValue = await this.FilterValueBinder.GetFilterValueAsync(context, filterDefinition, rawValue);

                    ReportCommandParameter reportCommandParameter = new ReportCommandParameter(parameterName, filterValue);
                    reportCommand.Parameters.Add(reportCommandParameter);
                }
                else
                {
                    throw new InvalidOperationException($"Filter definition for command parameter '{parameterName}' could not be found. (Command name is '{context.CommandName}'.)");
                }
            }

            return(reportCommand);
        }