For easy use and fast development. But also flexible for complex scenarios.
For ORMs, only concrete classes or static mapping (XML etc.) definitions has flexibility limitations.
Rapidex.Data allows to define entities with concrete classes or with JSON, YAML files.
Also entity definitions can be created with code in runtime.
public class Product : DbConcreteEntityBase
{
public string Name { get; set; }
public decimal Price { get; set; }
}thats all! No additional attributes or configuration required.
Or with JSON:
{
"type": "EntityDefinition",
"name": "Product",
"fields": [
{
"name": "Id",
"type": "long",
},
{
"name": "Subject",
"type": "string"
},
{
"name": "Customer",
"type": "reference",
"reference": "Contact"
}
//...
]
}Or with YAML:
_tag: entity
name: Product
fields:
- name: Id
type: long
- name: Subject
type: string
- name: Customer
type: reference
reference: Contact
#...Rapidex.Data allows to change entity definitions (metadata) and apply schema changes in runtime.
- You can add a new field to an entity and apply the schema change in runtime without stopping the application.
- You can add behavior to an entity in runtime.
Rapidex.Data use the UnitOfWork pattern to group multiple operations into a single transaction.
This ensures data integrity and consistency, especially in multithread applications.
var db = Database.Dbs.Db();
using var work1 = db.BeginWork();
//....
work1.CommitChanges();Rapidex.Data uses the behavior infrastructure to customize the definition and behavior of entities.
You can create reusable behaviors and attach them to multiple entities.
Validate, calculate, before save, after save and other logic can be injected with signal hub.
Much more possibilities with SignalHub structure.
See: Entity Logic
See: Signal Hub
Rapidex.Data ready for CRUD operations + web services implementation and provides built-in JSON deserialization support.
See: Serialization & Deserialization
See: Sample Application
Much applications need predefined data for some entities (like Country, Currency, etc.). Rapidex.Data provides an easy way to define and apply this data with YAML format.
See: Predefined Data
PartialEntity structure allows to defining a subset of fields to be retrieved or updated. This is useful for optimizing performance and minimizing data transfer.
See: Entity Definition
See: Updating Data
Some database engines (like PostgreSQL or MS SQL) support multiple schemas in a single database.
Rapidex.Data can use multiple schemas for workspace isolation. Each schema (workspace) can have its own set of tables (entities).
Some entities can be marked only base schema and shared between all schemas (workspaces).
var baseSchema = Database.Dbs.Db(); // default schema (name: 'base')
using var work = baseSchema.BeginWork();
//....
var schema1 = baseSchema.Schema("myOtherSchema"); // another schema (or workspace)
using var work = schema1.BeginWork();
//....An application can use multiple databases (especially can use MultiTenant applications).
var db = Database.Dbs.Db(); // default (master) database
//....
var otherDb = Database.Dbs.Db("otherDb");
//....See: Multiple Database Management
Different metadata customization for each database connection (each tenant can have different configuration)
Each database can have its own set of entities (tables) and may have different metadata definitions.
var db = Database.Dbs.Db(); // default (master) database
//....
var otherDb = Database.Dbs.Db("otherDb");
otherDb.Metadata.ScanDefinitions("..."); // scan entity definitions on folder (JSON, YAML files) for this database only
otherDb.Metadata.AddJson("...") // And/or add / modify entity definitions with another way
otherDb.Structure.ApplyAllStructure(); //Thats all! Apply schema changes for this database only
//....See: Multiple Database Management
Memory or distributed cache (Memory + Redis) support for entities and queries to improve performance.
See: Caching
Rapidex.Data has built-in support for complex queries and pagination.
See: Querying Data
Also supports filtering (from string expressions) with various operators.
See: Filtering
Color, Currency, Email, Image, Json, Password, OneWayPassword Phone, Text, Time, and others.
And expandable!
See: Field Types
Relationship support is designed with "field" infrastructure for easy development and end user experience.
RelationN2N and RelationOne2N field types are provide easy use of Many-to-Many and One-to-Many relationship support.
And this relationships is lazy and can be used in queries, filters, json serialization / deserialization etc.
See: Field Types
Reference, Relation, Enumeration and other complex field types are lazy loaded.
Rapidex.Data can automatically create and update database schema based on entity definitions with single command.
var db = Database.Dbs.Db();
//... scan definitions or add definitions with code
db.Structure.ApplyAllStructure(); //<-- Apply structure changesor
var db = Database.Dbs.Db();
var em = dbScope.Metadata.Get<Contact>();
em.AddFieldIfNotExist<string>("DynamicAddedField");
dbScope.Structure.ApplyEntityStructure<Contact>(); //<-- Apply structure changes for entity onlyTo avoid conflicts with predefined data and demo data, entity Ids always start from 10.000.
Developers can inject predefined data and demo data with Ids less than 10.000.
Query object provides a unique and easy way to create complex queries with filtering, sorting, pagination and includes.
var db = Database.Dbs.Db();
var query = db.GetQuery<Contact>()
.Like(nameof(Contact.FullName), "%a%")
.OrderBy(OrderDirection.Asc, nameof(Contact.FullName))
.IsNotArchived();
var result = query.Load();Query object also supports bulk update operations, allowing you to update multiple records in a single command.
var work = db.BeginWork();
var query = db.GetQuery<Contact>();
query
.EnterUpdateMode()
.Eq(nameof(Contact.Type), ContactTypeSample.Personal)
.Update(work, new Dictionary<string, object>() { { nameof(Contact.FullName), "Updated Name" } });
work.CommitChanges();For web services and dynamic queries, Rapidex.Data supports text-based filter parsing.
See: Filtering
Rapidex.Data supports metadata injection from another entity definition, allowing you to easily reuse and extend existing entity definitions.
_tag: entity
name: myEntity5
tenant: common
fields:
- name: Type
type: enum
caption:
isSealed: false
reference: ContactType
injection: # <- Inject to another entity definition
- entityName: myOtherEntity
fields:
- name: InjectedField
type: string
caption: InjectedField