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.
Rebelis of typeCouchDocumentas 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
Wherecalls; - 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)