DynORM is an open source project which develop a new ORM (object-relational mapping) that can work with relational data (tables and its records) which structure (set of fields, its type, set of constraints etc) can be changed even in run-time. “Dyn” for that
reasons stands for “dynamic”). DynORM is written on C# and available with its source code.

The main difference from other well-known ORM is that DynORM incorporates “convention vs configuration” approach. This ORM is almost zero-configuration. So instead of creating some huge amount of xml files that describe how your domain classes map to ER-model
you leave this work for DynORM. Focusing on development of your business logic layer (BLL) all interaction with database restricted to calling appropriate DynORM adapter’s methods when you need store, retrieve, update or delete your domain objects. Database
is used more like a “black box” in this concept. You do give up some control of how database objects named but, as advantage, all the work with database is accomplished automatically. For example, even when you modify your domain classes (say, you add some
new members, collections with related objects, etc) and after that connect with this recompiled code to database with the previous version of generated ER-model DynORM update it automatically in run-time and there is no need for you regenerate any xml mapping
files or do any other work.

DynORM has the following features:

it is almost zero-configuration ORM (you need to apply only several custom attributes to you BLL classes' members);

mapping CLR types to corresponding RDBMS' types is done automatically by DynORM. Not null constraint to fields (or in contrary nullability) in db applied automatically based on which CLR type was used to define corresponding class' member (all you
need to do is use nullable CLR types like int?, decimal? etc);

possibility of using composite primary keys (composed out of several class' members);

lazy loading can be applied when you retrieve objects from db;

optimistic lock logic is supported by DynORM automatically which gives you multy-user environment out of the box;

several modes of deletion, including cascade deletion;

several retrieving logics, including retrieving with predicate defined in terms of BLL classes' members (not db fields), retrieving the complete graph of related objects and some others;

there are custom attributes and appropriate implemented logic which helps to define classes with read-only members which identify objects and the object's parameterful constructors which DynORM will use automatically to create object and init those
id members.

you can define several types of relation between BLL classes (one-to-many, many-to-many etc) just using one custom attribute in your class definition;

it can work with different RDBMS engines:

MSSQL,

MySQL,

PostgreSQL,

Oracle.

Support of other RDBMS can be added by means of implementation IDAL interface (see documentation and source code for details);

although it doesn't need any configuration file which describes structure of tables it works with, it's possible to retrieve structure of data and data itself and serialize/deserialize it to/from xml;

just because DynORM can serialize/deserialize structure of tables and its records and because DynORM supports several RDBMS it can be used to easily deploy datastructure among servers with different database engines. Serialized structure of tables described
in CLR datatypes.

and some other features.

Without any additional forewords let take a look at quick example and how simply it can be used.
Suppose you have a business logic layer (BLL) class which is POCO (plain old C# object). In order to store the information encapsulated in this class' objects all you need is just apply several custom attributes to some members of the class.

As you can see, you just need to mark properties (or fields, but using of them is discouraged because properties give better encapsulation) which you want to use as identification of the class' objects with PrimaryKeyAttribute and fields you want to store
in database with FieldAttribute. You can optionally use TableAttribute attribute to give table that DynORM will create the name (by default the class' name is used). In order to store in database relation between objects you just need apply ForeignKeyDeclarationAttribute
(more about it in the examples in the following sections) and continue to use the class' member that references to related objects. You can apply several other attributes and its combinations to implement more complicated ER models but at minimum you need
only these several attributes.
You can use custom attributes without any parameters if you satisfied with defaults or can provide your preferences (like varchar type's length, numeric type's scale and precision):

Optionally, in order to use lazy logic, optimistic locking logic you can inhered your BLL class from BLLSuperType class.
After you've done this you just call BLLAdaptiveMapper's methods that help you to store, retrieve, update and, if necessary, delete objects like this:

When you create adapter connection string to your db and db type (MSSQL, MySQL, PostgreSQL, Oracle, etc) can be passed in ctor or can be defined in app config file. When you store the object DynORM discover object's structure (members that should be stored,
how object should be identified) and create necessary db objects (tables, relations) in run-time.
Later when you need to retrieve the stored object you can use the code like this (other retrieving logics are supported as well, inc retrieving with simple predicates, lazy loading, retrieve of complete graph of related objects and so on)

TestBLL retrievedObj = (TestBLL)mapper.Read(typeof(TestBLL), id);

Alternatively generic method can be used.

TestBLL retrievedObj = mapper.Read<TestBLL>(id);

Note, that non-generics methods of BLLAdaptiveMapper class are defined to receive object. The structure of the class which instance have been passed into mapper's method will be discovered in run-time. And in-run time DynORM will discover if there is an
appropriate table in db (and related db structures like constraints) to which connection string you passed to store the object. If there is such a table it will be used. Otherwise DynORM will create the table it need and store object's data in it.

How to start use DynORM in a project.

There are three steps that should be accomplished in order to start use DynORM in some project:
1. Add reference in the project to DynORM's assemblies;
2. Custom attributes should be applied to appropriate members of your BLL classes to make them storable in db (in order to use lazy logic, locking logic inhered your BLL class from BLLSuperType class);
3. Instanciate BLLAdaptiveMapper and use appropriate method of BLLAdaptiveMapper object when store, retrieve, update or delete your BLL classes' objects (you can provide mapper with connection string to your db and db type (MSSQL, MySQL, PostgresSQL, Oracle,
etc) passing them into its constructor or config file can be used).

DynORM adaptive mapper.

In general to interact with db you need to use one of the methods of BLLAdaptiveMapper.
BLLAdaptiveMapper implements IBLLAdaptiveMapper interface. The complete list of members of IBLLAdaptiveMapper interface is following:

All the non-generics methods defined to receive object because DynORM discover members of the object and create appropriate structures in db to store them in run-time. Structure of tables and relations between them in db is very similar to typical ER-model
used in relational databases traditionally except that all the tables and relations are made automatically. You can focus on implementation of you BLL delegating all the work with db to DynORM.

Examples of typical use-cases.

Supported data types.

DynORM supports almost all widely used base datatypes. In addition custom typed members can be defined in class (like RelatedObj property in the example below) and if ForeignKeyDeclarationAttribute attribute is applied to the custom type DynORM will create
separate table linked with foreign key constraint to the table of defining class to store the data (more about it in one-to-many and many-to-many sections).
It is possible to have any other members in the class that you need (methods, events, nested classes, not attributed with FieldAttribute and PrimaryKeyAttribute fields and properties and so on). DynORM can see only attributed with its custom attributes members.
Here is an example of class that defines several members with supported by DynORM datatypes:

Note that the class in the example above uses lazy loading logic and that's why DebuggerBrowsable(DebuggerBrowsableState.Never) attribute is applied. Otherwise data uploading will happen everytime you run the Visual Studio in debug mode when VS will try
to show the property's current value.
There is no need for properties to be auto-propery (defined like this { get; set; }). Getter and setter can be implemented and the logic in them will be triggered at the moment when DynORM will try to get or set values from them.
There is no differences in how you store and retrieve these objects using BLLAdaptiveMapper.
Lazy loading can be used when you load up related object as usual in DynORM as well.

When the class in the example above was stored in MSSQL we've got the following table:

One-to-many relation.

To implement relations between the classes you just apply ForeignKeyDeclarationAttribute attribute like in the following example.

ForeignKeyDeclarationAttribute attribute applied to class which will be a child in the relations. In ForeignKeyDeclarationAttribute attribute you need to declare parent type ((typeof(ParentTestBLL) in the example), relation quantity ( in the above example RelationQuantity.OneOrZeroToManyOrZero)
, class' member in the parent class that holds references to children (RelatedBLLObjs in our example) and an index of the foreign key (in most case it equals to 0, but it can be usefull if there several relations (foreign keys) between the same two classes).

In case of relations that have many entities appropriate class member should implement IList and IEnumerable interfaces. No attributes are required to the member. In case of “one-*” relations the member can be public readable and writable property or just a
public field. No attributes are required to the member.

Many-to-many relation.

Many-to many relation declared almost in the way as one-to-many. You need apply ForeignKeyDeclarationAttribute. The only difference is that the attribute should be applied to both classes that participate in the relation and the semantics of the attribute parameters
a bit differ (see example below). Behind the scenes DynORM automatically create link entity in database (the special table that implements many-to-many relation) and it will always know which one is service which relation based on the name convention used
in DynORM. It is even possible to have several many-to-many relation between the same two classes.
Here is an example of declaring the relation:

ForeignKeyDeclarationAttribute attribute applied to the classes which will be two sides in the relation. In ForeignKeyDeclarationAttribute attribute you need to declare parent type ((typeof(TestBLL1) in case of TestBLL2 and vise versa in the example), relation
quantity (in the above example RelationQuantity.ManyOrZeroToManyOrZero), class' member in the class that holds references to related objects (RelatedBLLObjs2 in case of TestBLL2 in our example) and an index of the foreign key (in most case it equals to
0, but it can be usefull if there several relations (link entities between the tables) between the same two classes).
There is no differences in how you store and retrieve these objects using BLLAdaptiveMapper.
Lazy loading can be used when you load up related object as usual in DynORM as well.

Lazy loading.

When you have production level complexity of ER-model you have very complicated net of relations between tables. When you retrieve an object from the database it can turn out into situation when you retrieve a hundred if not more of objects. And if that was
done just to read data from one member of retrieve object the overhead you created retrieveng all the related objects is not even necessary!
And in other cases you have cyclical references in you graph of related objects (the simplest example is many-to-many relation). So without any control of which object should be retrieve at which moment you can fall into endless loop.
In this case lazy loading pattern can help.
To use it in DynORM you need to accomplish several steps. Here is an example.
Suppose we define two classes like this:

Note that when you load lazy some object only its own fields are read. All the related object will be loaded up as soon as the first use of the property in which we store the children. That is why we have additional logic like in the example above in setter
and getter. Note that DebuggerBrowsable(DebuggerBrowsableState.Never) attribute is applied. Otherwise data uploading will happen everytime you run the code the Visual Studio in debug mode when VS will try to show the property's current value.
So now we can create and store the objects and afterward we will read the parent lazy (so child will be uploaded only at the moment of the first use of parent's property)

BLLSuperType-derived objects should be marked as loaded if children need to be stored as well as parent.
Lazy loading pattern in DynORM can be used only if your BLL classes derived from BLLSuperType. Otherwise exception will be thrown. In case of POCOs you can use only full read (not lazy read) logic.

Encapsulation of IDs properties.

For better encapsulation of properties in which you store values that identify you BLL object you can implement them as read-only properties. In this case you should define paramterful constructor of the object. The number, order and type of parameters should
be the same as the number, order and type of ids properties. This constructor should be attributed with PrimaryConstructorAttribute. After you've done this DynORM will be using this constructor when it will retrieve from db and instanciate objects. Here
is an example of the class with this constructor:

Optimistic lock logic.

In multy-user environment should some kind of a mechanism that would help to avoid situations when two or more users try to modify data at the same time. These is several approaches to do that but one of them is optimistic lock pattern. In order to use this
logic in DynORM all you need is just define a public read- and writable member in your class of int type and attribute it with OptimisticLockAttribute.
OptimisticLockAttribute attribute defined like this:

When you have this kind of class its object (when stored) will be checked automatically. If they have the actual version of data they can be stored in database otherwise an error occurs preventing “lost update” issue.

In conclusion.

There is always severe lack of the time to document all the necessary aspects of the implemented logic ))) Additional topics will be posted later. Please feel free to add your questions, comments, found bugs reports in discussion sections. Thank you in advance
for that! Hopefully the library will help in your projects!