Fast Object Relational Translation Engine


Keywords
database, orm, repository
License
MIT
Install
Install-Package JobTech.Forte.Data -Version 2.0.12

Documentation

Forte NuGet version (JobTech.Forte.Data)

A light-weight object-relational mapping (ORM) engine. It differs from traditional ORM's in the following ways:

  • There is no writing Linq-to-SQL like functionality or any other pseudo-SQL.
  • There is absolutely no dynamic SQL generation.
  • Object-relational mapping is done by convention not configuration

A Short Example

Consider the following console application making use of Forte to retrieve a list of customers.

public class Customer
{
	public int ID { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

class Program
{
	static void Main(string[] args)
	{
		var repository = new Repository<Customer>();
		var results = repository.SelectAsync().Result;

		foreach (var customer in results)
		{
			Console.WriteLine()
		}
	}
}

...and the SQL

CREATE TABLE Customer
(
	ID int IDENTITY(1,1) NOT NULL,
	LastName varchar(100) NOT NULL,
	FirstName varchar(100) NOT NULL
)

CREATE PROCEDURE SelectCustomer
AS
	BEGIN
	SELECT ID,
		   FirstName,
		   LastName
	FROM   Customer
END

Repository

The Repository<T> class contains four public methods you can leverage to implement your own custom repositories: Configure, SelectAsync, ExecuteAsync, Map.

In larger works (not a sample) there would likely be a more derived version and/or interfaces created in order to add functionality on top of what is provided with Repository<T>.

Configure

public static void Configure(ConnectionStringSettingsCollection connectionStrings, 
				int? commandTimeout = null)

The Configure method should be called once at application startup. Pass a ConnectionStringSettingsCollection into this method to manually configure your own named list ADO.Net data providers. For a .NET Core application, calling this method at startup is necessary if not using the old stype app.config settings and you need to set the providerName. Use the commandTimeout parameter to set a timeout for all commands executed through this Repository instance. The default value (null) will bypass setting the command timeout and fallback to the ADO.Net data provider default behaviour.

SelectAsync

public virtual async Task<IList<T>> SelectAsync(IDictionary parameters = null, CancellationToken cancellationToken = default);

The SelectAsync method is responsible for setting up and executing a stored procedure (or function if supported). The method will:

  • Bind input/output stored procedure parameters using the IDictionary passed into the method.
  • Connect to the underlying ADO.NET data provider and execute the stored procedure: Select[Typename].
  • Map and generate a list of objects (of type T) from records returned as an IList.
  • Capture any return value and/or exceptions raised from the stored procedure.

ExecuteAsync

public virtual async Task ExecuteAsync(T item, TransactionType transactionType, 
						IDictionary parameters = null, CancellationToken cancellationToken = default);

The ExecuteAsync method is responsible for generating and executing a transactional stored procedure. The method will:

  • Bind input/output parameters to/from properties (i.e. non-public) taken from the object passed into the method (T item).
  • Bind values to/from the (optional) IDictionary passed into the method.
  • Connect to the underlying ADO.NET data provider and execute the stored procedure: Insert[TypeName] | Update[TypeName] | Delete[TypeName].
  • Capture any return value and/or exceptions from the stored procedure.

The IDictionary passed into both the SelectAsync and ExecuteAsync methods will be used to read input parameters and store any output parameters.

Map

public virtual IList<T> Map(IDataReader reader);

The Map method is called from the SelectAsync method with the resulting IDataReader. Unless overridden, the base method will automatically map fields to properties by name using the first result set returned from the stored procedure.

Bind

protected virtual void BindInput(DbCommand cmd, IDictionary parameters);
protected virtual void BindInput(DbCommand cmd, T item, IDictionary parameters);
protected virtual void BindOutput(DbCommand cmd, IDictionary parameters);
protected virtual void BindOutput(DbCommand cmd, T item, IDictionary parameters);

The Bind virtual methods allow full control over the binding process (exchanging program variables with stored procedure parameters). Override these methods in descendent classes to enhance or replace the default binding logic.

More detailed examples are included in the Examples project here.