In this post, we'll see how to query CouchDB
from C#
using LINQ!
I am going to use my library that after few years, today it reached v3.0.0: CouchDB.NET.
What's CouchDB
Apache CouchDB is a distributed document database and its replication protocol is available from servers to mobile phones and web browsers.
It speaks JSON
natively, and that's great when using Javascript
, but when using .NET
it might be painful because of JSON's dynamic nature.
How CouchDB.NET can help
If you worked with Entity Framework
before, this library might look familiar.
The setup
Create your CouchContext
with the list of databases you have and configure authentication.
Rebel
is of typeCouchDocument
as it contains things like Id, Rev, Attachments, and others.
public class MyDeathStarContext : CouchContext
{
public CouchDatabase<Rebel> Rebels { get; set; }
protected override void OnConfiguring(CouchOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseEndpoint("http://localhost:5984/")
.EnsureDatabaseExists()
.UseBasicAuthentication(username: "anakin", password: "empirerule");
}
}
Use LINQ
The library supports native .NET LINQ, ven the SQL-like syntax.
await using var context = new MyDeathStarContext();
var skywalkers = await context.Rebels
.Where(r =>
r.Surname == "Skywalker" &&
(
r.Battles.All(b => b.Planet == "Naboo") ||
r.Battles.Any(b => b.Planet == "Death Star")
)
)
.OrderByDescending(r => r.Name)
.ThenByDescending(r => r.Age)
.Take(2)
.Select(
r => r.Name,
r => r.Age
})
.ToListAsync();
What is sent to the database
{
"selector": {
"$and": [
{
"surname": "Skywalker"
},
{
"$or": [
{
"battles": {
"$allMatch": {
"planet": "Naboo"
}
}
},
{
"battles": {
"$elemMatch": {
"planet": "Death Star"
}
}
}
]
}
]
},
"sort": [
{ "name": "desc" },
{ "age": "desc" }
],
"limit": 2,
"fields": [
"name",
"age"
]
}
It will automatically optimize the query.
Just to name a few:
- Merge multiple
Where
calls; - Remove useless condition from the filter (like
Where(r => true || r.Age == 19)
); - Convert
SingleOrDefault(d => condition)
toWhere(d => condition).Take(2).SingleOrDefault()
; - Convert
Max(d => d.Property)
toOrderByDescending(d => d.Property).Take(1).Select(d => d.Property).Max()
Other features
In the year, more and more features have been added.
For example:
- Adding/Updating/Deleting documents;
- Adding/Updating/Deleting indexes;
- Database spitting;
- Views;
- Local documents;
- Users management;
Dependency Injection
If you work with Asp.NET Core
a DI package is available.
It just as easy as register the dependency in the Startup
:
services.AddCouchContext<MyDeathStarContext>(builder => builder
.UseEndpoint("http://localhost:5984")
.UseBasicAuthentication(username: "admin", password: "admin"));
Then just inject the context:
public class RebelsController : Controller
{
private readonly MyDeathStarContext _context;
public RebelsController(MyDeathStarContext context)
{
_context = context;
}
}
Finally
If you work with CouchDB
and C#
I highly suggest checking the library (even if it might result in more bugs to fix for me).
You can see all that it offers in the README and let me know what you think.
Top comments (0)