Advanced programming


You can add additional tables and fields to the existing iPlus database. Since you cannot change the entity framework models (* .edmx) from gip.core.datamodel or gip.mes.datamodel, you have to add your own model in your custom assembly. NOTICE: We support Entity Framework Core 7 (.NET 7) but the documentation is not finshed yet.

Of course, you can also create your own database and use iPlus. However, it doesn't matter which of the two variants you prefer, the work steps are the same in both cases:

  1. Create a new assembly.
  2. Generate an entity framework data model.
  3. Replace T4 template.
  4. Extend database context class with iPlus features.
  5. Deploy updates using SQL scripts.
  6. Add partial entity classes.

 

 

You can download this sample project in the download area


Use Visual Studio to add a new assembly project (.NET framework> 4.7.1). 

Please note the iPlus naming conventions when naming your assembly, otherwise it will not be recognized during the registration process. (The registration process is carried out during login by holding down the Ctrl key and pressing the login button). We recommend ending the file name with "*.datamodel.dll" .

In the sample project we have named it mycompany.package.datamodel.dll.


Before reading further, please familiarize yourself with creating Entity Framework data models.

Then create the model using the  "database-first approach" and "reverse engineering" because this is supported by iPlus. You can also use the code-first approach, but you will have to do the migration yourself. The migration or automatic update of the database tables is provided in iPlus using SQL scripts, which is described in more detail later in section "E. Providing updates using SQL scripts". 

The ACObjectContextHelper class was briefly discussed in the previous chapter. It is an auxiliary class for extending the "System.Data.Objects.ObjectContext" class to include iPlus features (such as length checks, min / max values, automatic setting of time stamps, default values, extended reference checks when deleting ...). For this reason iPlus currently only supports "Entity Framework 4" for these additional features and therefore the Entity Framework generator in Visual Studio should not generate the DBContext class. Code generation is explained in more detail in the next section.

If you want to do without the iPlus validation functions, the automated context management and the database queues, you can also use the newer versions of the Entity Framework.

In both cases, create the "* .edmx" file for the first time using the generator for EF-6 (DBContext) provided by Visual Studio and the edmx file is entered in the project tree.


So that the code generator does not generate DBContext, but ObjectContext, you must delete the tt templates added by Visual Studio in the tree and replace them instead with a T4 template for ObjectContext & iPlus framework, which you can copy from the sample project (mycompany.tt).

Rename the "mycompany.tt" template to the same name as your *.edmx file (see example image above). Open the T4 template in the code editor and enter your *.edmx file name in the SourceCsdlPath property:

 

Before you run the T4 template, you should  convert the property names for navigation properties into a "more readable format". There is the tool "gip.tool.entitywizzard.exe" in the iPlus installation directory. Start the program and select your "*.edmx" file:

 

Then run the T4 template.

 

How to update the model

Whenever you have updated your edmx model, the same order applies:

  1. If you are asked by the generator when saving the edmx model whether you want to run the T4 template, confirm with "No".
  2. Run gip.tool.entitywizzard.exe.
  3. Run the T4 text template.

 

 

After executing the T4 template, the generated C# file is inserted below the T4 template. In the example, the file is named mycompany.cs and the class was declared as follows:

public partial class MyCompanyEntities : ObjectContext 

To add the iPlus features, create a new C# file with a new class that inherits from the class that generated the T4 template. In our example, the MyCompanyDB class that inherits from MyCompanyEntites:

 

Provide MyCompanyEntites with the ACClassInfo attribute class of type "Global.ACKinds .TACDBAManager". With this setting, you announce your new database context class to the iPlus framework so that it appears in the iPlus development environment in the iPlus application tree (after you have started iPlus with the Ctrl key). 

(If you  create your database model using the  model-first approach, you must also provide your context class with the ACClassInfo attribute class as described above.)

MyCompanyEntites must also omplement the gip.core.datamodel.IACEntityObjectContext interface. To do this, instantiate the auxiliary class ACObjectContextHelper. The methods and properties of this class are named exactly the same as those in the IACEntityObjectContext interface. So all you have to do is delegate the method calls in your class to the ACObjectContextHelper instance and you have expanded your context with iPlus features.

(The use of the iPlus features (ACObjectContextHelper) is not possible with the model-first approach and therefore you have to implement the interface yourself)


If you have made changes in tables, fields and relations and have updated your edmx model, your software will not yet work for other customers because the installation there must also be updated to the latest database.

The iPlus update system does this for you. Before the actual assembly registration process, which you start with the Ctrl key when you log in to iPlus, SQL scripts can be executed automatically. This update logic is implemented in the assembly "gip.core.dbsyncer.dll". The following settings must be made for this to work:

 

  1. Create a folder with the name "DbScripts".
  2. Create a subfolder that is named with a name of up to 10 characters. "MyCompDB" in the example above.
  3. Create an info.xml file in this folder with the following content:

 

 

4. Enter the name of the folder in the <DbSyncerInfoContextID> element in which this xml file is located.

5. Enter the name of the entity container in the <ConnectionName> element, which also corresponds to the class name that the T4 generator has created.

6. You can enter any description text in the <Name> element.

7. The info-xml must always be copied into the bin directory during the build. Therefore, set the property "Copy to output directory" to "Always copy" or "Copy if newer".

 

From this moment on, your project can now be updated. Any future database changes you make on your development system must be added as an SQL script in your project folder. Also set it like "info.xml" to "Always copy" so that the SQL script is copied into the build directory for later deployment. If there are different edmx models that work with the same database, the scripts must be synchronized with one another across all contexts. So that the DB-Syncer (gip.core.dbsyncer.dll) does this in the correct order, the SQL script file names must be assigned according to a defined naming scheme, which contain an exact time stamp :

dbsync_YYYY-MM-DD_hh-mm_developername.sql

The developername can be replaced by the actual developer, department or company name. This then appears in the SQL change history that is stored in the table [@DbSyncerInfo]:

 

The column names in the table [@DbSyncerInfoContext] correspond to the element names in the info.xml file. (The Order field is irrelevant, you can use any number).

 

Important: ConnectionStrings.config = SQL scripts!

The ConnectionString.config must have a separate <add> section for each edmx model or for each entity container name. For "gip.core.datamaodel.Database" the entity container name is "iPlusV4_Entities". For "gip.mes.datamodel.DatabaseApp" it is "iPlusMESV4_Entities".

SQL update scripts are executed on the database that is set in the corresponding connection string. This allows you to control whether you want to manage or update a database separate from iPlus or whether you want to add your custom tables to the iPlus database! In both cases, however, the change history is written to the iPlus database!

 


The Entity Framework Generator generates the following framework signature based on the T4 template:

public partial class Material : VBEntityObject, IInsertInfo, IUpdateInfo, IDeleteInfo

gip.core.datamodel.VBEntityObject is the base class for all entity classes so that the additional iPlus features can be used. It specifies a number of virtual methods and common functionalities that can be overwritten or reused in the derivations. The interfaces IInsertInfo, IUpdateInfo and IDeleteInfo are added automatically because the T4 template in the edmx model examines the entities according to the fields "InsertDate, InsertName, UpdateName ...".

Then program the rest of the program code in another C# file where you extend the partial class (see F in the first picture above). The partial class should be expanded with the following color-coded code areas:

 

Partial class definition (A)

Add a partial class definition.

 

Classes and property description using attribute classes 

(A) & (B):  Add an  ACClassInfo attribute class  (A) with Global.ACKinds .TACDBA  (B). This is how you announce this entity class to the iPlus framework. It then appears in the development environment below the associated database context class in the iPlus application tree (this also applies to the  model-first approach).

(C): Since the properties of the entity class are declared in the other partial class created by the T4 template generator, the ACClassPropertyInfo attribute cannot be declared there, because it will be removed by running again the T4 template. Instead, use the ACPropertyEntity attribute class (C). For each database field or property of the entity class, you declare an ACPropertyEntity line and enter the name of the property in the first parameter. The remaining construction parameters are the same as for the  ACClassPropertyInfo class. For string properties (SQL type varchar), enter the maximum length of the string with "MaxLength".

However, if you use the model-first approach (by foregoing the iPlus features), you can use the ACClassPropertyInfo attribute as normal for your properties.

(D):  Optional: Define a template for the storable queries (ACQueryDefinition). A storable query should always be defined if the table (or the entity class) in business objects is the main table which is filtered and navigated to.

(F): Optional: Define an ACSerializable attribute so that a smart pointer to an object of this entity class can be used in a network capable property.

 

Implementation of VBEntityObject

VBEntityObject has several virtual methods with a standard implementation for adding, deleting and changing objects. Overwrite this if you want to add your individual logic and call the basic implementation at the end of the method.

(A): To add new objects, declare a static method with the following signature:

public static MyEntityClassT NewACObject(MyDbContextClass dbApp, IACObject parentACObject, string secondaryKey)

In this method, you then create a new instance of the entity class (MyEntityClassT) and set the primary key with a new GUID (B) .

(C): Then call the extension method DefaultValuesACObject() so that all properties of your entity class or generally of an IACObject are initialized with the default values ​​that have been configured in the development environment.

(D): If your table has a secondary key (a database field with a legible key), you can use the number generator to generate it and pass it to the "secondaryKey" parameter. The number ranges of the number generator can be configured with the business object gip.bso.iplus.BSONoConfiguration in advance.

(E): Call the SetInsertAndUpdateInfo() method to have the user name and the current time entered in the "Insert" fields.

Attention: The object is not yet in change tracking! Either add the newly generated object immediately to the DB context or do it outside of the NewACObject() method.


Due to the T4 text template and the Entity Wizard tool, you should stick to the following conventions so that your later LINQ queries are easy to read for other developers:

  1. Use primary key of the type (GUID / uniqueidentifier) (1) .
  2. Name the primary key like the table name and add "ID" at the end. e.g.  "InOrderPosID" (2).
  3. Foreign keys should be named so that they end with the name of the primary key of the referenced table (3).
  4. You can optionally use cascaded deletion (e.g. header and position tables) (4).