Problem
How to use Azure NoSQL database in ASP.NET Core.
Solution
Create a class library and add NuGet package: Microsoft.Azure.DocumentDB.Core
Add a class to encapsulate settings:
public class AzureNoSqlSettings
{
public AzureNoSqlSettings(string endpoint, string authKey,
string databaseId, string collectionId)
{
if (string.IsNullOrEmpty(endpoint))
throw new ArgumentNullException("Endpoint");
if (string.IsNullOrEmpty(authKey))
throw new ArgumentNullException("AuthKey");
if (string.IsNullOrEmpty(databaseId))
throw new ArgumentNullException("DatabaseId");
if (string.IsNullOrEmpty(collectionId))
throw new ArgumentNullException("CollectionId");
this.Endpoint = endpoint;
this.AuthKey = authKey;
this.DatabaseId = databaseId;
this.CollectionId = collectionId;
}
public string Endpoint { get; }
public string AuthKey { get; }
public string DatabaseId { get; }
public string CollectionId { get; }
}
Add a class for repository, which will work with a generic type. Add a constructor and private
methods to initialize the Azure client:
public AzureNoSqlRepository(AzureNoSqlSettings settings)
{
this.settings = settings ?? throw new ArgumentNullException("Settings");
Init();
}
private AzureNoSqlSettings settings;
private DocumentClient client;
private void Init()
{
client = new DocumentClient(
new Uri(this.settings.Endpoint), this.settings.AuthKey);
CreateDatabaseIfNotExistsAsync().Wait();
CreateCollectionIfNotExistsAsync().Wait();
}
private async Task CreateDatabaseIfNotExistsAsync()
{
await client.ReadDatabaseAsync(
UriFactory.CreateDatabaseUri(this.settings.DatabaseId));
}
private async Task CreateCollectionIfNotExistsAsync()
{
await client.ReadDocumentCollectionAsync(
UriFactory.CreateDocumentCollectionUri(
this.settings.DatabaseId, this.settings.CollectionId));
}
Add methods to get one or more items:
private Uri GetCollectionUri()
{
return UriFactory.CreateDocumentCollectionUri(
this.settings.DatabaseId, this.settings.CollectionId);
}
private Uri GetDocumentUri(string documentId)
{
return UriFactory.CreateDocumentUri(
this.settings.DatabaseId, this.settings.CollectionId, documentId);
}
Now add public
methods for the repository:
public async Task<List<T>> GetList()
{
var query = this.client
.CreateDocumentQuery<T>(GetCollectionUri())
.AsDocumentQuery();
var results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
public async Task<T> GetItem(string id)
{
Document document = await this.client.ReadDocumentAsync(GetDocumentUri(id));
return (T)(dynamic)document;
}
public async Task<Document> Insert(T item)
{
return await this.client.CreateDocumentAsync(GetCollectionUri(), item);
}
public async Task<Document> Update(string id, T item)
{
return await this.client.ReplaceDocumentAsync(GetDocumentUri(id), item);
}
public async Task<Document> InsertOrUpdate(T item)
{
return await this.client.UpsertDocumentAsync(GetCollectionUri(), item);
}
public async Task Delete(string id)
{
await this.client.DeleteDocumentAsync(GetDocumentUri(id));
}
Inject and use repository:
public class MovieService : IMovieService
{
private readonly IAzureNoSqlRepository<Movie> repository;
public MovieService(IAzureNoSqlRepository<Movie> repository)
{
this.repository = repository;
}
In ASP.NET Core Web Application, configure services:
public void ConfigureServices(
IServiceCollection services)
{
services.AddScoped<IAzureNoSqlRepository<Movie>>(factory =>
{
return new AzureNoSqlRepository<Movie>(
new AzureNoSqlSettings(
endpoint: Configuration["NoSql_Endpoint"],
authKey: Configuration["NoSql_AuthKey"],
databaseId: Configuration["NoSql_Database"],
collectionId: Configuration["NoSql_Collection"]));
});
services.AddScoped<IMovieService, MovieService>();
services.AddMvc();
}
Discussion
The sample code will require you to setup Azure account, NoSQL database and collection. Instructions for these could be found here.