Skip to content

ATF.Repository - is an object-oriented data access technology. It is an object-relational mapping (ORM) solution for bpm`online.

License

Notifications You must be signed in to change notification settings

vladyslav-kapliuk/repository

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

ATF.Repository - is an object-oriented data access technology. It is an object-relational mapping (ORM) solution for bpm`online from Advanced Technologies Foundation.

This is an external library and not a part of bpm`online kernel.

General features:

  • working with data via models;
  • building direct and reverse data dependencies via models;
  • creating, modifying and deleting data with the help of models with business logic implementation.

Repository

Repository (ATF.Repository.Repository) - is a storage and model generator. All models should be created via the repository. All changes are applied via the repository.

Creating a repository instance:

var repository = ClassFactory.Get<IRepository>();
repository.UserConnection = UserConnection;

Saving changes:

repository.Save();

Model

Model - basic unit of data modeling. It is connected to the Entity. The model is inherited from an abstract BaseModel class (ATF.Repository.BaseModel). It is marked with the Schema attribute (ATF.Repository.Attributes.Schema). Model properties, connected to the Entity fields, are marked with SchemaProperty attribute (ATF.Repository.Attributes.SchemaProperty).

Attention! The type of property must be the same as the type of data in connected column.

Note. It is not required that the title of the model and its properties matches the title of the schema and its fields.

Example:
[Schema("TsOrderExpense")]
public class Expense : BaseModel {

	// Connection with the "Type" lookup field
	[SchemaProperty("Type")]
	public Guid TypeId { get; set; }

	// Connection with the "ExpenseDate" Date-Time field 
	[SchemaProperty("ExpenseDate")]
	public DateTime ExpenseDate { get; set; }

	// Connection with the "Amount" decimal field 
	[SchemaProperty("Amount")]
	public decimal Amount { get; set; }

}

Direct connection setup

To set up direct connection, add a property of a model type to the model and mark it with the LookupProperty attribute (ATF.Repository.Attributes.LookupProperty).

Example:
[Schema("TsOrderExpense")]
public class Expense : BaseModel {

	// Connection with the "Order" lookup field
	[SchemaProperty("Order")]
	public Guid OrderId { get; set; }

	// Setting up direct connection with the Order model, using the value of "Order" lookup field
	[LookupProperty("Order")]
	public virtual Order Order { get; set; }

}

[Schema("TsOrder")]
public class Order : BaseModel {

	// Connection with the "Amount" Decimal field
	[SchemaProperty("Amount")]
	public decimal Amount { get; set; }

}
Example of using direct connection
var amount = expenceBonus.Order.Amount;

Reverse connection setup

To set up reverse connection, add a property of List<T> type to a master model, where "T" states for a detail model.

Example:
[Schema("TsOrderExpense")]
public class Expense : BaseModel {

	// Setting up reverse connection with the ExpenseProduct model, using the name of detail entity schema column for link.
	[DetailProperty("TsOrderExpense")]
	public virtual List<ExpenseProduct> ExpenseProducts { get; set; }

}

[Schema("TsOrderExpenseProduct")]
public class ExpenseProduct : BaseModel {

	//Entity schema TsOrderExpenseProduct contain column TsOrderExpense
	//but we shouldn't add property with map on that column if we want to create reverse connection

	// Connection with the "Amount" Decimal field
	[SchemaProperty("Amount")]
	public decimal Amount { get; set; }

}
Reverce connection use case
var expenseProducts = expense.ExpenseProducts.Where(x => x.Amount > 100m);

Creating a new model instance

A model is created by calling a CreateItem<T> method and specifying the model type. Upon that, properties, connected to the Entity, will be populated with default values.

var bonusModel = repository.CreateItem<Bonus>();

Receiving the model by existing data from the repository

Existing model is read by means of calling a GetItem<T> method, where Id - is the identifier of the existing record.

var bonusModel = Repository.GetItem<Bonus>(Id);

Model data changing

bonusModel.Amount = 100m;

Deleting model instance from the repository

Model instance is deleted by calling DeleteItem<T> method, where model - is the instance to be deleted.

Repository.DeleteItem<Bonus>(model);

Lazy loading

Models setup allows lazy loading of models by direct and indirect connections. To launch lazy loading add virtual modifier to the property.

In the following example values of Order and Products properties will be loaded at once. Values of Document and Expenses properties will be loaded at the moment of the first applying.

Note. If possible, lazy loading is recommended.

[Schema("TsOrderExpense")]
public class Invoice : BaseModel {

	[LookupProperty("Document")]
	public virtual Document Document { get; set; }

	[LookupProperty("Order")]
	public Order Order { get; set; }

	[DetailProperty("InvoiceId")]
	public virtual List<Expense> Expenses { get; set; }

	[DetailProperty("InvoiceId")]
	public List<InvoiceProduct> Products { get; set; }

}

Using basic mechanisms of data access

Working with models does not exclude usage of data access basic mechanisms - both via EntitySchemaQuery (Terrasoft.Core.Entities.EntitySchemaQuery) and Select (Terrasoft.Core.DB.Select).

These approaches are shown in the following example:

[Schema("TsOrderExpense")]
public class Expense : BaseModel {

	public decimal BonusProductAmountSumm() {
		var select = new Select(UserConnection)
			.From("BonusProduct")
			.Column(Func.Sum("Amount"))
			.Where("Id").IsEqual(new QueryParameter(Id)) as Select;
		return select.ExecuteScalar<decimal>();
	}

	public decimal BonusProductPrimaryAmountSymm() {
		var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "BonusProduct");
		var primaryAmountColumnName = esq.AddColumn(esq.CreateAggregationFunction(AggregationTypeStrict.Sum, "PrimaryAmount"));
		var collection = esq.GetEntityCollection(UserConnection);
		return collection.Count > 0
			? collection[0].GetTypedColumnValue<decimal>(primaryAmountColumnName.Name)
			: 0m;
	}
}

About

ATF.Repository - is an object-oriented data access technology. It is an object-relational mapping (ORM) solution for bpm`online.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 100.0%