Search code examples
c#sdkgenexus

GeneXus Extensions - How to know the DataStore associated to a table?


I need to make a GeneXus extension that goes through the tables of the DEFAULT DataStore (but not in the other datastore) to do certain checks.

What is the best way to know the datastore associated with a table?

I can check if the table is referenced by a DataView, but maybe there is a better method.


Solution

  • Currently there is no straightforward API that solves this query. The way things are modeled is that the DataView is the entity that associates a Table to a DataStoreCategory.

    Checking the cross-reference is a nice way to narrow down the problem space, although to be certain that a given data view is bound to a given table, you have to check for the AssociatedTableKey property.

    Another thing to keep in mind, is that there could be a data view associated to a table in the DEFAULT data store, or more than one data view bound to the same table and different data stores. There are no guarantees that the model is in a valid state at any moment, and deciding how to handle these situations may affect how you build your query.

    This sample query returns all tables associated to a data store. If there are multiple data views associated to the table, it checks if the first of them belongs to the given data store.

    IEnumerable<Table> GetTablesInDataStore(DataStoreCategory ds)
    {
        foreach (EntityKey tblKey in Table.GetKeys(ds.Model))
        {
            if (IsInDataStore(tblKey, ds))
                yield return Table.Get(ds.Model, tblKey.Id);
        }
    }
    
    bool IsInDataStore(EntityKey tblKey, DataStoreCategory ds)
    {
        DataView dv = GetDataView(ds.Model, tblKey);
        if (dv is null)
            return ds.IsDefault;
        else
            return Artech.Genexus.Common.Properties.XFL.GetDatastore(dv).Identifier == ds.Id;
    }
    
    DataView GetDataView(KBModel model, EntityKey tblKey)
    {
        foreach (var r in model.GetReferencesTo(tblKey, LinkType.UsedObject, new[] { ObjClass.DataView }))
        {
            var dv = DataView.Get(model, r.From.Id);
            if (dv.AssociatedTableKey == tblKey)
                return dv;
        }
        return null;
    }