Build Status

Data Access Layer Generator

Genie is a cross platform .Net library that can generate a data access layer for any .Net or .Net Core application using a relational database.

Genie has written in C# for .Net core framework

Genie can create a .Net standard class library that can be used as an interface to access any relational databse.

Getting Started

How It Works

Genie CLI

Genie CLI is a simple CLI Program that uses Genie core library to trigger a generation. This is bundled with the release.

Command Line Arguments for CLI

How to install

After downloading the latest release for your OS , extract the archive and put in some place , add the path to the PATH variable.

After that you can call Genie by executing GenieCLI command .

Configuration

It should be something like this

connectionString

A connection string that points to the target database. this connection string is only used to read database meta-data.

projectPath

Path to the project (Data access layer of the target system). This path should point to a existing directory.

baseNamespace

The base namespace of the data access layer (ex :Example.DataAccess)

projectFile (optional)

The relative path to the project file from project path. this is an optional property. if this is provided the generator will add necessary packages to the project file. and if the project file is not there , Genie will create it

abstractModelsLocation (optional)

Genie can generate set of interfaces for every relation and view in thee specified location.

abstractModelsNamespace (optional)

Namespace of the generated interfaces. all interfaces will be in the same interface

enums (optional)

List of table details that can be used as enums. if a table has predefined set of rows which need to be accessed often,this table can be used as an enum table.

example :

the OrderType table (ID, Name) has 3 rows and these rows do not change. we can use this table as an enum table and can be defined in the configuration file as

this will result a class which has static members for each row and and those members can be implicitly converted to the specified type.

the resulting class will be something like this.

Generated DAL

The generated DAL uses Dapper (micro ORM) to map objects and to access the database.

Implements unit of work pattern and repository pattern. each table and view has a model object and a repository.

All repositories can be accessed through a unit of work.

the DapperContext,should be a singleton. UnitOfWork, DapperContext can be implemented using a DI Container in an upper layer.

Repositories

UnitOfWork can be used to access the repositories. Unit() function in the DapperContext can be used to create new Unit A repository contains methods to get, add, update, remove database entities all unit of work objects must be used in a using block.

a unit has the Commit method that can be used to commit changes to the database

Procedures

All Stored procedures of the the database can be accessed through the Procedures object of any Unit Of Work object, all the parameters of the methods are nullable and null by default. A generic parameter should be provided in order to execute a procedure and the result will be mapped to the given class type.

There are three functions for each procedure (List, Single and Void) List is for getting list of objects as the result Single is for getting single object as the result Void is for no result

Querying

DAL provides an easy way to filter objects. this is a Builder like pattern to filter objects. there is a QueryContext implemented for all repositories. user can access it through the Get() method of any repository. the Get method returns a QueryContext that is specific for the object type of the repository.

QueryContext

A QueryContext contains some methods to filter, order, page the result

Where

There is a FilterContext that can be used to filter the query there is a property for each column and these properties can be used to chain the complete filter expression. each two expressions should be connected using And || Or , however if you do not specify a boolean operator between two expressions it will be and by default.

there is a filter for every data type and every filter contains methods to filter the property. the Filter() method returns the parent QueryContext.

OrderBy

There is a OrderContext that can be used to order the query there is a property for each column and these properties can be used to chain the complete order expression. an order expression can be Descending or Ascending.

the Order() method returns the parent QueryContext.

Page

The Page function can be used to add paging to the query.

Top

Add a limit to the query.

Skip

Skip can be used to skip certain rows from the query result.

Take

Skip can be used to Take only certain rows from the query result. Skip and Take can be used together to page the result.

Query Function

The Query function ends the QueryContext and returns the query result.

Count Function

The Count function returns the count of the result.

Filter

This function needs an IEnumerable<IPropertyFilter> which is a collection of property names, operations and values(if necessary) . this method can be used to filter the result in a customizable way How the operations are filtered and what are the operations :

Transactions

You can start a transaction by calling BeginTransaction method in the UnitOfWork then you should pass the transaction to all methods you use in repositories. you can use the Commit method in the UnitOfWork to commit the transaction.