The AfterLoaded method is intended to be used to customize the data dictionary at runtime. Why not just do this in Stonefield Query Studio? There may be many reasons:

  • Perhaps you don't want certain users to access certain tables. In that case, you want to set the Reportable property of the appropriate ITable objects to false based on the user name. While you could use role-based security for this, doing it in the AfterLoaded method makes it more dynamic.

  • If you allow your users to customize the caption for certain fields, or even add their own custom fields to the tables, you want Stonefield Query to know about the changes the user made.

  • If users can purchase your application by module, you don't want those tables belonging to modules the user hasn't purchased listed in Stonefield Query.

This method is called immediately after Stonefield Query loads the collections from the data dictionary database. So, you have full access to the collections without altering the data dictionary database. Note that the data dictionary is loaded before any user logs in, so there's no selected data source yet. If your code needs to access the data source, such as to customize the data dictionary based on some data in the database, use the AfterLogin method of an application plugin instead.


public void AfterLoaded()




Here's an example that adds custom fields the user has added to their tables to the Stonefield Query data dictionary. It assumes there's a table called CustomFields in the application's database that defines the custom fields. In this table, the Table column contains the name of the table the field was added to, Name contains the field name, Type contains the data type, and Heading contains the caption for the field.

using System.Collections.Generic;
using System.Data;
using Stonefield.Query.Application;
using Stonefield.Query.ConnectionManagement;
using Stonefield.Query.DataDictionary;
using Stonefield.Query.Plugins;
namespace SamplePlugins
        Version = "",
        ExecutionPriority = 5)]
    public class SampleDataDictionaryPlugin :
        public ISQApplication Application { get; set; }

        public IDataDictionary DataDictionary { get; set; }
        /// <summary>
        /// Add custom fields defined in the CustomFields table
        /// to the data dictionary.
        /// </summary>
        public void AfterLoaded()
            // Get a connection object for the current datasource.
            IDataSource ds = Application.ConnectionManager.DataSources.CurrentDatasource;
            IDatabase database = Application.DataDictionary.Databases[0];
            IConnectionFactory factory = ds.GetConnection(database.Name)
                as IConnectionFactory;
            IConnection conn = factory.CreateConnection();
            // Get the CustomFields table.
            DataTable result = conn.ExecuteSQLStatement("select * from CustomFields",
                null, "CustomFields");
            // Add each custom field to the data dictionary.
            foreach (DataRow row in result.Rows)
                string tableName = row["Table"].ToString();
                ITable table = Application.DataDictionary.Tables[tableName];
                string fieldName = row["Name"].ToString();
                IField field = Application.DataDictionary.Fields.New(tableName +
                    "." + fieldName);
                field.Caption = row["Heading"].ToString();
                field.DataType = System.Type.GetType(row["Type"].ToString());
                field.Table = table;

        public void BeforeLoaded()
        public string GetVersion(IField item)
            return "";
        public string GetVersion(ITable item)
            return "";
        public string GetVersion(IJoin item)
            return "";

See Also

Data Dictionary | Plugins