The Cloud Spanner NHibernate Dialect is now Generally Available
Introduction
Installing
Install the Spanner NHibernate dialect:
From our partners:
dotnet add package Google.Cloud.Spanner.NHibernate --version 1.0.0
Connecting
Connect to Cloud Spanner with NHibernate:
using NHibernate;
using NHibernate.Cfg;
Configuration = new Configuration().DataBaseIntegration(db =>
{
db.Dialect<SpannerDialect>();
db.ConnectionString =
"Data Source=projects/MY-PROJECT/instances/MY-INSTANCE/databases/MY-DATABASE";
});
var sessionFactory = Configuration.BuildSessionFactory();
using var session = configuration.SessionFactory.OpenSession();
var transaction = session.BeginTransaction();
var singer = new Singer
{
FirstName = "Jamie",
LastName = "Allison"
};
await session.SaveAsync(singer);
await transaction.CommitAsync();
Usage
The Cloud Spanner NHibernate dialect supports standard NHibernate features, like querying data using both the NHibernate Criteria API and Linq, managing associations and executing transactions. The dialect also supports specific Spanner features such as interleaved tables, mutations and stale reads.
Query with Linq
NHibernate 3.0 introduced the Linq to NHibernate provider. The Spanner NHibernate dialect implements translations for the most commonly used functions and operators so these can be used with LInq.
using var session = configuration.SessionFactory.OpenSession();
var singersBornBefore2000 = await session
.Query<Singer>()
.Where(s => s.BirthDate < new SpannerDate(2000, 1, 1))
.OrderBy(s => s.BirthDate)
.ToListAsync();
Console.WriteLine("Singers born before 2000:");
foreach (var singer in singersBornBefore2000)
{
Console.WriteLine($"\t{singer.FullName}, born at {singer.BirthDate}");
}
var singersStartingWithAl = await session
.Query<Singer>()
.Where(s => s.FullName.StartsWith("Al"))
.OrderBy(s => s.LastName)
.ToListAsync();
Console.WriteLine("Singers with a name starting with 'Al':");
foreach (var singer in singersStartingWithAl)
{
Console.WriteLine($"\t{singer.FullName}");
}
Interleaved Tables
Using interleaved tables for parent-child relationships in your schema can improve performance. Interleaving a child table with a parent means that the child records will be stored physically together with the parent. These relationships can be modeled and used as any other association in NHibernate.
using var session = configuration.SessionFactory.OpenSession();
using var transaction = session.BeginTransaction();
// Create a Singer, Album and Track.
// Album references Singer with a normal foreign key relationship.
var singer = new Singer
{
FirstName = "Farhan",
LastName = "Edwards",
};
var album = new Album
{
Title = "Thinking Jam",
Singer = singer,
};
// Track is interleaved in Album. This means that Track must use a composite primary
// key. In this example, the primary key is the Album ID and a Track number.
var track = new Track
{
// A TrackIdentifier consists of the parent Album and a track number.
TrackIdentifier = new TrackIdentifier(album, 1L),
Title = "Always Sweet",
};
await session.SaveAsync(singer);
await session.SaveAsync(album);
await session.SaveAsync(track);
await transaction.CommitAsync();
Mutations
NHibernate will use Data Manipulation Language (DML) by default. You can instruct NHibernate to use mutations for all transactions that are executed using a specific NHibernate session, or for a single transaction.
var sessionFactory = configuration.Configuration.BuildSessionFactory();
// Create a session that will always use mutations.
using var session = sessionFactory
.OpenSession()
.SetBatchMutationUsage(MutationUsage.Always);
// Create a new Singer and save it. The insert will use a Mutation.
var transaction = sessionUsingMutations.BeginTransaction();
var singer = new Singer
{
FirstName = "Wanda",
LastName = "Yates",
};
await session.SaveAsync(singer);
await transaction.CommitAsync();
// You can also instruct a single transaction to use mutations.
using var session2 = sessionFactory.OpenSession();
var transaction2 = session.BeginTransaction(MutationUsage.Always);
Further Samples
The GitHub repository contains a directory with multiple samples for common use cases for working with NHibernate and/or Cloud Spanner.
Limitations
Cloud Spanner features that are not supported in NHibernate are listed here.
Getting Involved
We’d love to hear from you, especially if you’re a .NET developer considering Cloud Spanner or an existing Cloud Spanner customer who is considering using NHibernate for new projects. The project is open-source, and you can comment, report bugs, and open pull requests on Github.
By: Knut Olav Løite (Software Engineer)
Source: Google Cloud Blog
For enquiries, product placements, sponsorships, and collaborations, connect with us at [email protected]. We'd love to hear from you!
Our humans need coffee too! Your support is highly appreciated, thank you!