Element Search

The Element Search is the central point to obtain any kind of information about the contents of the project. Open the Element Search by selecting Project -> Search for elements in the main menu, or by clicking the Element Search button on the toolbar. Element Search allows you to write any Linq query (or plain, imperative C# / VB.NET if you prefer that) in the editor and run it on the loaded project and collect the results.

Element Search Query Window

Element Search Query pane

These results are then displayed on the second tab, which offers the feature to export the data to an external file in various formats, send it to a plug-in, a group, a model view or a typed list, if applicable. The different parts of the Element Search are described below.

Query Specifics tab

The query specifics tab is the tab where you specify your query and also run it. The following elements are available:

Element type
This is the return type of the enumerable returned by the query, or in case of enumerable, just IEnumerable and in case of scalar, object. The return type is used by the results tab to determine which columns to display and how to interpret the results in a typed manner, for example to enable various export options for the data.
Language
This is the programming language in which the query is written. This language is controlled by the SearchQueryDefaultLanguage designer preference
New button
This button clears the editor so you can define a new query
Run query button
This button takes the code written in the editor, compiles it using the compiler for the language specified and runs the code. If no compile errors occur and no exceptions during runtime, it will display the results in the Results tab. If there are errors / exceptions, they are displayed in the Error List pane docked at the bottom of the main window.
Editor pane
The editor pane consists of three parts: the top part and bottom part are read-only and are pre-filled with code to make the query runnable. The middle part is editable and this is the area where you define the query. Each Element type chosen will pre-fill this middle pane with an example to get you started. The middle pane supports intellisense (not inside linq lambdas). The code you write will be part of the Search method, which signature header is displayed in the top part and the closing statement in the bottom part.

Results tab

When the query is error free and returns a result, it's displayed on the Results tab. The results tab consists of a read-only grid which displays the objects returned by the query and contains a button at the bottom, Export results to.. which allows you to export all data to an external file (HTML, Excel, text file, XML file) or, if applicable, add the elements to a group, send the data to a plug-in, create a new typed list from the elements (if they're entities) or add them to a model view (if they're entities).

Writing queries

All queries have to be compilable by .NET 4.0 and you can use any type available in the namespaces given in the using / imports statements at the top of the top part of the Editor pane. For every Relational Model Data storage container found in the project, a constant is created with the Driver ID associated with the storage container. This allows you to access some data (e.g. mappings for a particular database) without having to hunt down the Driver ID for a particular database.

The currently loaded project is the sole input of the Search method (which you are implementing using the editor pane) and any public method or property (and the objects returned by those methods / properties) are available to you in the query. This means that you can obtain any element in the project using the rich API implemented on the Project object and use it in your query. To learn more about the API available, please consult the LLBLGen Pro Core Assemblies reference manual, which describes (in the ApplicationCore assembly) the complete object model available through the Project object.

Saving element search queries in the project file

The LLBLGen Pro designer allows you to save an element query in the project file. Per element type / language combination, you can store queries under a unique name by using the Save / Save as buttons. A saved query is stored inside the project file and can be re-executed by simply selecting it from a drop down combo box.

The saved query combo box is filled with the known saved queries if the language and / or element type combo boxes selections are changed. Selecting a saved query will place the query's text in the query area, replacing whatever text the area contained. The query is then ready to be executed. To delete a saved query, you select the query and click the Delete button.There's no undo for saving a query into the project.

Examples

To get you started, below are a few example queries which show some of the power of Element Search.

Example 1: to retrieve all entities in the inheritance hierarchy of an entity called "WorkItem".

To achieve this, we can use the following query (using Entity as Element Type)

var root = p.EntityModel.Vertices.First(e=>e.Name=="WorkItem");
var toReturn = new List<EntityDefinition>(p.GetAllSubtypesForEntity(root));
toReturn.Add(root);
return toReturn;
Dim root = p.EntityModel.Vertices.First(Function(e) e.Name="WorkItem")
Dim toReturn = New List(Of EntityDefinition)(p.GetAllSubtypesForEntity(root))
toReturn.Add(root)
Return toReturn

Example 2: All entities and their mapped targets, per database

To obtain all entity definitions and the targets they're mapped on, plus the information which database this target is located, use the following query (using Enumerable as Element Type):

var q = from e in p.EntityModel.Vertices
        from m in p.GetAllMappingsForGroupableModelElement(e)
        select new
        {
            EntityName = e.FullName,
            Driver = CoreStateSingleton.GetInstance()
                    .GetDriverConfigurationFromCache(m.DriverID).DatabaseShortName, 
            Mappedtarget = m.MappedTarget==null? "<null>" : m.MappedTarget.FullName
        };
return q;

Example 3: All field mappings and mappings per entity per database

To obtain all field mappings combined with the mapping of the entity the fields are part of per database, use the following query (using Enumerable as Element Type):

var q = from e in p.EntityModel.Vertices
        from m in p.GetAllMappingsForGroupableModelElement(e)
        from f in e.Fields
        let fm = m.GetFieldMappingOfField(f)
        select new 
        { 
            EntityName = e.FullName, 
            Driver = CoreStateSingleton.GetInstance()
                    .GetDriverConfigurationFromCache(m.DriverID).DatabaseShortName, 
            Mappedtarget = m.MappedTarget==null? "<null>" : m.MappedTarget.FullName,
            FieldName = f.Name,
            MappedFieldTarget = fm.MappedTarget==null ? "<null>" : fm.MappedTarget.FieldName
        };
return q;