Working with data in code
The JetVeo platform utilizes Entity Framework for data access and management.
Representation in code
Data you define in the Data section will be available in code.
- Entities represented as classes with the same name
- Aspects represented as interfaces with the same name
- Codebooks represented as enum-like classes with the entries being the codebook codes
Working with the database
In the code, you have access to the Application Database. It is passed to you as an argument in Business Commands and in simple expressions. You can then pass it as an argument to your custom code.
The type of the database object is AppDatabase
.
Get database data
For each entity defined in data, there is a corresponding entity table. Accessible at db.ExampleEntitySet
db.ExampleEntitySet
is an IQueryable object. You can further specify what objects you want to get by doing queries. More about queries
Most common queries
Where(x => condition(x))
Contains elements, for which the passed lambda expression is true.Count(x => condition(x))
Returns the number of elements, for which the lambda evaluates to true.Any(x => condition(x))
Returns a boolean value: true if any object x specified by the lamda exists, false otherwise.FirstOrDefault(x => condition(x))
Returns the first element, that satisfies the condition. Otherwise returns null or other specified default value.SingleOrDefault(x => condition(x))
Returns the only single element, for which the condition is true. Otherwise returns null or other specified default value.
Modifying the database
Add
You can add an entity object to the database by calling db.ExampleEntitySet.Add(entity)
Documents
When creating an entity object, the document fields are implicitly set to null. When adding it to the database,
the document are set to IDocument objects with 0 revisions. To assign an actual document, use the AddRevision
method on the IDocument object.
Delete
You can delete an element, or a collection of elements:
Delete(x)
Deletes the elementx
.DeleteRange(xs)
Deletes all elements fromIEnumerable<T> x
that are in the db table.
We generally advise against using these methods, because they are destructive. Instead, we recommend adding an attribute deleted
, as you can ignore the objects with this attribute set, while still allowing for their restoration.
Modify
You can modify an entity object in the database by setting a value to some of it's field.
If this change violates any requirement defined in the App (Invalid state transition, Forbidden null reference...), this action will throw an exception.
For a state machine like this:
The following code will throw an exception. Unless the exception is handled, the command will fail.
var deletedEntity = db.ExampleEntitySet.FirstOrDefault(x => x.Status == ExampleCodebook.DELETED);
if (deletedEntity != null)
{
deletedEntity.Status = ExampleCodebook.ACTIVE;
}
Staged transactions
The changes to the database (Adding, modyfing, deleting) an element will be staged. The changes will apply only after the code has been sucessfully executed. (No uncaught exceptions, No negatve result returned).
If you add an element x to the database, you won't be able to find it until the staged changes are made.
public void ExampleDbAdd(AppDatabase db, long Id)
{
var exampleObject = db.ExampleEntitySet.Add(new ExampleEntity() { ExampleId = Id }); // Adds to the database
bool inDatabase = db.ExampleEntitySet.Any(x => x.ExampleId == Id); // false
...
}
After this method is executed, the exampleObject
will be added to the database, but inDatabase
will evaluate to false
Keeping track of the staged changes is often useful. These are stored in the entity table .Local
. Reffering back to
the previous case, the queries will evaluatr as shown below.
public void ExampleDbAdd2(AppDatabase db, long Id)
{
var exampleObject = db.ExampleEntitySet.Add(new ExampleEntity() { ExampleId = Id }); // Adds to the database
bool inDatabase = db.ExampleEntitySet.Any(x => x.ExampleId == Id); // false
bool inLocal = db.ExampleEntitySet.Local.Any(x => x.ExampleId == Id); // true
...
}
A commonly used pattern in a command is checking the local database for an object, and then looking into the application database. This might come useful when parsing data in a command, and collision control is needed.
var found = db.ExampleEntitySet.Local.FirstOrDefault(x => x.ExampleId == Id) // Note the Local collection use
?? db.ExampleEntitySet.FirstOrDefault(x => x.ExampleId == Id); // Fallback to DB query