C# Driver for Cassandra: New Mapper and Linq improvements
We are excited to introduce you the new object Mapper component which simplifies mapping query results to objects and also the several improvements made to the Linq component that are providing a friendlier and more powerful interface.
Mapper
The new Mapper, originally developed by Luke Tillman as a separate project called CqlPoco, is a lightweight object mapper that lets you write queries with CQL, while it takes care of mapping rows returned from Cassandra to your classes. It was inspired by PetaPoco, NPoco, Dapper.NET and the cqlengine project.
Quick example
Create a new Mapper instance using the constructor on the Cassandra.Mapping namespace
IMapper mapper = new Mapper(session);
For a given POCO:
public class User { public Guid UserId { get; set; } public string Name { get; set; } }
Now you can execute a query and get the result automatically mapped to the User class:
IEnumerable<User> users = mapper.Fetch<User>("SELECT userid, name FROM users");
New Mapper instances can be created each time they are needed, as short-lived instances, as long as you are reusing the same Session instance.
The Mapper provides methods for Inserts, Updates, Deletes, selecting a single record and more, including their async
counterparts. Check out the Mapper documentation for more information and code samples.
Linq
We added several improvements to the Linq component of the driver:
- Mapping configuration can be specified using a fluent interface
- Support for append and prepend to collections
- CQL functions support (token, maxTimeuuid, minTimeuuid)
- Case insensitivity option
- Ignore properties.
With the Linq capabilities of the driver you can query your Cassandra cluster using Linq lambda syntax or Linq queries and get your results mapped to your classes or even anonymous classes.
Using a Linq query
var query = from user in users where user.Group == "admin" select user; IEnumerable<User> adminUsers = query.Execute();
Using lambda syntax
IEnumerable<User> adminUsers = users .Where(u => u.Group == "admin") .Execute();
There are several Linq samples on the Linq documentation.
If you are already using Linq with previous versions of the driver, there are no breaking changes for Linq in this release but be sure to check out the Linq upgrade guide.
Configuring mappings
In many scenarios, you need more control over how your class maps to a CQL table. You have two ways of configuring Linq and the Mapper:
- decorate your classes with attributes
- define mappings in code using the fluent interface
An example using the fluent interface:
MappingConfiguration.Global.Define( new Map<User>() .TableName("users") .PartitionKey(u => u.UserId) .Column(u => u.UserId, cm => cm.WithName("id")));
You can specify partition and clustering keys amongst several other table and column attributes, and define how those fields map to your classes.
You can also create a class to group all your mapping definitions.
public class MyMappings : Mappings { public MyMappings() { // Define mappings in the constructor of your class // that inherits from Mappings For<User>() .TableName("users") .PartitionKey(u => u.UserId) .Column(u => u.UserId, cm => cm.WithName("id"))); For<Comment>() .TableName("comments"); } }
Then, you can assign the mappings class in your configuration.
MappingConfiguration.Global.Define<MyMappings>();
Other changes in 2.5
Version 2.5 also features an Address translator interface, that you can set at Cluster level, for a greater flexibility in node discovery.
The driver is now delivered in a single strong named assembly, check out the 2.5 upgrade guide for more information.
The new 2.5 version of the C# Driver is now available on NuGet and the source code is on GitHub.