Brief base description
From the very beginning, the Eloquera database was written to store objects based on the .Net Framework, which made it possible to try to absorb all the best from object and relational databases at the same time, overcoming many of their differences. Theoretically, Eloquera can work with any languages from the .Net Framework family, however, in practice, the work has been checked so far only with C #. The main focus of developers on the enterprise segment (100+ GB), and not on the embedded solution, although the latter are also not deprived of attention.
The distinctive features of Eloquera are very impressive and are constantly replenished, here is a very short list of them:
- Saves C # objects (any objects of any language on the .Net platform) without the need to implement special interfaces and adapters.
- Saves Dynamic objects with any fields \ properties and can match them to objects of any type.
- The query language is as close to SQL as possible, and no relational SQL database is required. Plus LINQ support.
- Returns objects as they were stored (including enumerated types)
- Support for parameters in the form of lists and arrays
- Regular expressions in queries.
- Support for template objects.
- Restore Read-only fields and properties.
- Partial return of objects is supported. For example, if you need the ForumTopic class, then you can not pull up all the links to ForumMessages.
- You can specify the depth of the object to return in the query.
- Stored procedures.
Installation
You can
pick up base distribution
kits from the official website
www.eloquera.com after registration. You can choose from archives for the desktop installation and for installation as a service (x86 or x64). When installing Eloquera as a service, there are no pitfalls.
Installation on any more or less modern machine will take no more than 5 minutes. After which at your disposal will be:
- Eloquera Config Studio;
- Eloquera DB Studio;
- The service itself is responsible for the operation of the database.
The desktop version is installed on the x-copy principle, i.e. you just need to copy the files to the desired directory. To work, you will need the .Net 4 Full Framework installed.
')
With this approach, the NuGet package looks quite expected, but at the moment there is no such thing yet. However, the developers are aware of this possibility and are threatening to create such a project soon, as soon as the kernel for the standalone version of the base is formatted as a library and not an executable file.
Base Modes
Eloquera DB can work in several modes:
- Common database for multiple applications, standard mode.
- In-memory mode.
- Desktop - mode built into the application database.
Code to connect to the server and create a database:
private const string DBName = "ServiceDatabase"; using (var eloquera = new DB("server=localhost:43962;options=none;")) { eloquera.CreateDatabase(DBName); eloquera.OpenDatabase(DBName); eloquera.Close(); }
The
DB class is used to connect to the database
. The class constructor is passed the connection string, in this example the connection goes to the service.
Eloquera supports in-memory mode as when working as a service, and when working offline (desktop mode). In the free version, the base in memory can take up to 1 GB. It is also worth remembering about the physical availability of RAM, as it is possible that the size of the database will be such that Windows will try to place it in the paging file on the disk. As you know, this does not add speed at all.
In order to indicate to the engine that we want to create a database in RAM, it will be necessary to specify a special
inmemory parameter in the connection string.
new DB("server=(local); options=inmemory;"))
In this case, the database will exist only in RAM, but
an empty file will still be created in the file system . In order to be able to resume work with such a database, you must use the
persist parameter in the connection string in the options
For work in desktop mode, the connection string will be:
new DB("server=(local); options=none;"))
In order for Eloquera to work in Desktop mode, you need to stop the EloqueraDB service, otherwise you will get an error saying that it is impossible to connect to the service at the address
(local).A lot of interesting things in the database, but I will stop on the most interesting probably.
JOINs
The general syntax of the operation:
SELECT Alias1,Alias2 FROM Type1 Alias1 [ LEFT | RIGHT| INNER | FULL ] JOIN Type2 Alias2 ONSomeFunction(Alias1.Field1, Alias2.Field2)
If two different types or more were used in building a query using JOIN in a SELECT, then the result of such an operation will be a new IEnumerable <Dictionary <string, object >>.
JOIN queries, like other types of queries, can use named parameters. Including in the expression ON. However, there are some limitations to keep in mind:
- The parameter value must be defined before the query starts.
- Named parameters cannot be used to replace type names in a Select statement. Those. an attempt to call the select type will be outside the rules.
We should also mention how the issue is solved with the heirs of the classes involved in the construction of the JOIN expression. The standard behavior is considered the possibility of using inherited types in a query. For example, if TypeC is inherited from TypeA, then the expression:
SELECT a, b FROM TypeA a INNER JOIN TypeB b ON b.id = a.id
can return TypeC objects in the “a” field if they satisfy the conditions of the expression. In order to get rid of all the descendants of the class in the query results, you should use the word ONLY. Those. rewrite the query like this:
SELECT a, b FROM ONLY TypeA a INNER JOIN TypeB b ON b.id = a.id
Now in the "a" will be only objects of type TypeA.
Example in pictures to work Inner Join. Suppose we have the following data structure:

Our task is to find all the schools and jobs that are in one place.
Code:
var queryResult = (IEnumerable<Dictionary<string,object>>) db.ExecuteQuery("SELECT sch, wp FROM School sch INNER JOIN WorkPlace wp ONch.Location=wp.Location");
The results in the form of a table can be represented as follows:
#
| queryResult [“sch”]
| queryResult [“wp”]
|
one
| School1
| wPlace2
|
2
| School2
| wPlace2
|
3
| School3
| wPlace3
|
four
| School3
| wPlace4
|
Options
Parameters can only be used to transfer data to a request, so it’s useless to fantasize about getting data through parameters.
Using parameters is very simple:
Parameters param = db.CreateParameters(); param["name"] = "John"
To use a parameter in a request, you must use an overloaded method that accepts them. For example:
var res = db.ExecuteQuery("SELECT BasicUser WHERE Name = @name", param);
The array of parameter values can be interpreted by the base as a simple array:
Parameters param = db.CreateParameters(); param.AddList("emails", new string[]{"john@gmail.com", "david@hotmail.com"}); var res = db.ExecuteQuery("SELECT BasicUser WHERE ALL @emails in Emails", param);
Parameters can be used with Top, Skip and Order By. Parameters can also contain null.
Stored procedures
Starting with version 4.0, Eloquera supports stored procedures.
Stored procedures can be considered as extension methods to the main base. They are written using C #, for which thanks to the creators, for not having invented any of their interpretable dialect for this business. It turns out that you can use the entire .Net feature when writing procedures.
So, words suffice, it is better to show how stored procedures are created in practice.
The first step is to declare the interface with the desired procedures. This interface must be on the client and server side.
public interface ICityStatisticSP{ CityCars GetCityCars(string cityName); }
Then we create a class that will be needed only on the server side. In this case, the library with the implementation of the procedure must be placed in the Lib folder in the base directory, or the path to the libraries with stored procedures can be configured using the
StoredProceduresPath parameter.
public class CityStatisticSP: StoredProcedure, ICityStatisticSP { public CityCars GetCityCars(string cityName) { Parameters parms = db.CreateParameters(); parms["city"] = cityName; var cars = db.ExecuteQuery("SELECT Car FROM Car JOIN Seller ON Car.SellerID = Seller.ID WHERE Seller.City = @city", parms) .OfType<Car>() .ToList(); … } }
Adding new procedures does not require restarting the database service.
After you have thrown the library with the procedures to the server, you can call the procedure on the client with the following code:
ICityStatisticSP procedures = db.GetStoredProcedureClass<ICityStatisticSP>(); string cityName = "Chicago"; CityCars cars = procedures.GetCityCars(cityName);
Based on the very object nature of the database, it is not necessary to configure the mapping configuration procedure and other things-other things.
The presence of stored procedures in the existing form solves more complex problems than the simple saving and re-invoking requests to the database. It is worth emphasizing that
all code is executed on the side of the base . Those. With the help of procedures, you can greatly reduce the load on the network, when using procedures you can more effectively filter data on the server side, based on the results of filtering, for example, create new elements and store them in the database. I think that it is not difficult to imagine a situation when it is necessary to add a set of elements from the base with some value. Under the old approach, we would have to unload all the elements, create a selection of conditions for updating, update, and transfer the new data back to the network. The stored procedure will solve such problems much more efficiently.
Dynamic objects (Dynamic)
According to the developers of Eloquera, they added a bit of magic to the object base and got a unique functionality and object, which was called Dynamic. You have already guessed where the legs grow from this feature, and with which it is ideologically aligned in C #. Dynamic objects can store in themselves as structured data, i.e. classes and structures defined by you in C # code, and arbitrarily compiled. At the same time, you can freely represent these objects as each other.
The main advantage is the ability to add and remove fields from a saved object - the data will magically join and integrate into the object.
Advantages that provide dynamic objects:
- They are easy to create and use. No need to worry about missing fields and properties. Any number of fields of any type can be added at runtime.
- They automatically determine the type of field and work with it in accordance with its capabilities and limitations. Dynamic objects fully support indexing.
- They can refer to each other and be contained in each other.
- Dynamic objects are very, very fast.
- They can be converted on the fly to "native" objects and back .
- Work does not require a data scheme, which gives a very wide field of activity.
- Engines for blogs, CMS, wiki
- Profiles and user registration
- Storing the history of records
- Cases when the data should be filtered or aggregated at runtime.
- Applications that operate on variables with a number of attributes of different types.
Regarding the last two points, it is necessary to clarify that we mean various programs that allow users to independently construct data types, dynamically make up an interface for each user. There is no rational possibility to keep such data in strict form without explosive complexity. Using Dynamic allows you to describe such types in an infinite variety and work with them in the same style.
Another example is Web 2.0, where users can add their own comments to everything, associate materials, and so on. With traditional relational databases, hard class descriptions, such schemes are impossible or very difficult to implement.
A quick overview of working with dynamic objects
The structure of dynamic objects can be modified at any time along with the contained data. Together with ease of use, it provides more than ample opportunities for data evolution.
Dynamic @do = new Dynamic(); @do["Title"] = "Some title"; @do["Price"] = 14.99; @do["DateAdded"] = DateTime.Now; db.Store(@do); Dynamic res = (from Dynamic d in db where d["Price"] == 14.99 select d).First<Dynamic>();
The same is possible with the use of variables of type dynamic presented in .Net 4.
dynamic @do = new Dynamic(); @do.Title = "Some title"; @do.Price = 14.99; @do.DateAdded = DateTime.Now; db.Store(@do); dynamic res = (from Dynamic d in db where d["Price"] == 14.99 select d).First<Dynamic>();
Please note that when using LINQ, you must use
d [“Price”] to explicitly indicate the construction of the expression tree.
When working with dynamic objects, it is possible to find out all the fields that the object contains:
Dynamic @do = dynamics[0]; foreach (var field in @do) { Console.WriteLine(String.Format("Field Name {0} Value {1} Type {2}", field.Key, field.Value, field.Type)); }
In addition to the wide possibilities, there are some limitations, in particular, there is a list of characters that cannot be used when specifying field names. This is aimed at avoiding collisions while writing SQL queries to objects. Here is a list of reserved characters:
.,%] [+ - $! * ()
I hope that you will be interested in the base and at least take a base on a note for home experiments.
I can organize a cycle of articles if it is interesting, the material is ready.