📜 ⬆️ ⬇️

WildData: easy data access framework

Good day,% username%! So I decided to write an article on this resource. It will be about access to data from applications written in .NET, in particular in C #. All my thoughts, and in what they eventually poured out, I will try to present under the cut. Welcome!

Under the DBMS in the article we will understand the relational DBMS. Looking ahead, I will say that the presented library (framework) is not a substitute for the Entity Framework, does not depend on it and has nothing to do with it.

Nevertheless, we will push away from the above framework. One of his ideas is an attempt (and a very successful one) of introducing an abstraction of access to data. In other words, avoiding a particular DBMS.

Each DBMS has its advantages and disadvantages: some have some capabilities, some others; some do one thing well, others do another, etc. Let's now imagine that, after weighing all the pros and cons, we chose a certain DBMS for implementing some kind of grand (or not) project and decided to write all this using ... ADO.NET.
')
ADO.NET advantages:

  1. full control over requests;
  2. relative simplicity: create a connection, create a transaction (optional), create a command, add query text and parameters, start, read data (optional);
  3. There is support for almost any DBMS.
  4. close interaction with the DBMS (for example, support of such “non-standard” data types as coordinates, JSON, etc.).

Disadvantages of ADO.NET (prerequisites for project implementation):

  1. for each model, it is necessary each time to re-write the code to read, add, and change a record in the database — in other words, displaying an object on a record in a table, view, etc. and, conversely, the display of the record on the object;
  2. There is no abstraction in Java (although there are DbConnection / DbCommand and other classes, but specific types are often used, for example, SqlConnection / SqlCommand);
  3. There is no universal support for working with the package of records (add, update, add or update, delete);

Most likely the reader has already guessed that we will think how to get rid of the aforementioned shortcomings. Let's talk about what is the key to the implementation of the entire project.

Let's start in order.

  1. So what can we do to write this code once? First of all, we note that the backbone for reading one or several objects remains unchanged regardless of what kind of object it is and what fields it contains. This means that we need a universal function of reading a single object. The same is true for adding and updating a record.

    How should such a function be written? The first thing that comes to mind is Reflection. Let's say. But Reflection has one major drawback - it is slow. If when reading / adding / changing / deleting a single object, the speed will not be significant, then with a large number of objects, the overhead will be noticeable.

    We will come to the aid of the Expression'y and the possibility of compiling them on the fly. The idea is that the function body is generated, compiled, and a reference to it is stored as a delegate. It is necessary to do this only once - during initialization.

    What should the functions work with? With three entities:

    • object as such (model);
    • data reading object (for example, SqlDataReader);
    • collection of parameters (for example, SqlParameterCollection).

    In order for the point of generation of these functions to be united, the following wrapper interfaces are introduced: IDbParameterCollectionWrapper and IReaderWrapper (see link to the project repository below). For each DBMS, it is necessary to implement these interfaces individually. Looking ahead: the framework is aimed primarily at speed, so in some cases deferred ("lazy") initialization is used. The framework also contains several auxiliary attributes for greater flexibility (for example, calculated fields, required fields, etc.).

  2. The entire common part of the framework is in a separate common project. For the user, the interfaces are mostly visible. It is highly recommended to use only interfaces.

  3. Batch work with records has not yet been implemented, but this is already a “technical matter”.

The project can already be tested (see links below). Linq support is available! The project is in alpha version, so the code is not perfect yet.

What is planned to add:


References:

» WildData project on GitHub.
» WildData Nuget Package.
" Nude-package WildData (implementation for PostgreSQL).
» A very simple example of using the framework.

Strictly ask not to judge. This is my first article on habrahbr. Thanks for attention!

PS For all questions I ask in a personal and comments.

Source: https://habr.com/ru/post/314198/


All Articles