Dook!
.NET Core light object mapper for SQL databases.
Features
- Class to database table mapping using decorations (optional).
- Built in transactions.
- LINQ to SQL query translation (still working on this).
- It uses FastMember to assign query column values to object properties.
- Easy to setup.
Getting started
Prerequisites
- This package was made with .NET Standard 2.0, so .NET Core 2.0+ is required for it to work. You could use this package with other frameworks as .NET Framework, but only its .NET Core implementation will be covered here. You can check framework compatibilities here.
- For now, only SQL Server and MySQL databases are supported.
Installing
You can install this package via Nuget.
Application Setup
First of all, lets create a class. This class will be associated with a table in the database:
public class Example : IEntity
{
public int Id { get; set; }
public int IntProperty { get; set; }
public string StringProperty { get; set; }
}
You can decorate your class to map it according to your database naming conventions:
[TableName("examples")]
public class Example : IEntity
{
[ColumnName("id")]
public int Id { get; set; }
[ColumnName("int_property")]
public int IntProperty { get; set; }
[ColumnName("string_property")]
public string StringProperty { get; set; }
}
Second, lets derive a Context class. This class is intended to manage the connection and transactions with a specific database.
public class MyContext : Context
{
public MyContext(DookConfigurationOptions<MyContext> configurationOptions) : base(configurationOptions)
{
}
}
Lets add an EntitySet to MyContext. The EntitySet class is responsible for making CRUD operations over a single database table. In this case, we will add an EntitySet to manage Example table.
public class MyContext : Context
{
//Always declare your EntitySets as properties
public EntitySet<Example> ExampleRepository { get; set; }
public MyContext(DookConfigurationOptions<MyContext> configurationOptions) : base(configurationOptions)
{
ExampleRepository = new EntitySet<Example>(QueryProvider);
}
}
Now, lets configure Dook into our application. In Startup.cs, add the following inside the ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
//..other configuration code..
services.AddDookContext<MyContext>(options => {
options.ConnectionString = "YourConnectionString";
//Here you choose which kind of database will you use.
options.DatabaseType = DbType.MySql;
});
//.. more configuration code here
}
With all the above done, you are ready to write queries and commands to database.
Querying
List<Example> examples = _context.ExampleRepository.Where(x => x.IntProperty >= 3).OrderByDescending(x => x.StringProperty).ToList();
Important: the alias you use in the lambda expressions (int this case, x) will be the same used in the resulting query. Keep it consistent!
Inserting data
_context.ExampleRepository.Insert(example);
_context.SaveChanges();
Note: this assumes the Id field is an autoincremental PK on database. After running the Insert command, the object will receive a new Id from database.
Updating data
_context.ExampleRepository.Update(example);
_context.SaveChanges();
Note: this will work only if the updated object has a valid Id (distinct from zero).
Deleting data
_context.ExampleRepository.Delete(example);
_context.SaveChanges();
Note: this will work only if the deleted object has a valid Id (distinct from zero). Important: insert, update and delete commands are run inside a transaction. Always remember to call the SaveChanges(). Otherwise, the transaction will be rolled back.
Versioning
Using SemVer for versioning.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Part of the code is based on Matt Warren's work: https://blogs.msdn.microsoft.com/mattwar/2008/11/18/linq-building-an-iqueryable-provider-series/.