Highlights

  • No compile-time configuration required.
  • Reduce development time by writing less data access code.
  • Easy to learn with a simple, uniform, and succinct syntax.
  • Lower code maintenance costs with a flexible and easy to evolve data model.
 

Write less code

Developers access a database system using Slazure’s dynamically typed objects that do not require any form of schema definitions; writing data access code has never been easier:

// C# example: How to create a MongoDB document.
dynamic storage = new DynStorage("mongodb://user:pass@example.org/MongoDBExample");

// Get reference to the Employees document collection - it's created if it doesn't already exist
dynamic employeesCollection = storage.Employees;

// Create a document in the Employees collection for John with his email as the document id - the document is created if it doesn't already exist
var employee = employeesCollection.Document("j.doe@example.org");
employee.Name = "John Doe";
employee.Salary = 50000; // John earns $50k/year
employee.Birthdate = new DateTime(1995, 8, 18); // John was born 08/18/1995

// Save the document to the MongoDB database
employee.Save();
// C# example: How to create a Azure Table Storage entity.
dynamic storage = new DynStorage("UseDevelopmentStorage=true");

// Get reference to the Employees table, it's created if it doesn't already exist
dynamic employeesTable = storage.Employees;

// Create an entity in the Employees table for John with his email as the PartitionKey, the entity is created if it doesn't already exist
var employee = employeesTable.Entity("j.doe@example.org");
employee.Name = "John Doe";
employee.Salary = 50000; // John earns $50k/year
employee.Birthdate = new DateTime(1995, 8, 18); // John was born 08/18/1995

// Save the entity to the Azure Table Service storage
employee.Save();
// C# example: How to create a DocumentDB document.
dynamic storage = new DynStorage("URL=https://contoso.documents.azure.com:443/;DBID=DDBExample;TOKEN=VZ+qKPAkl9TtX==");

// Get reference to the Employees document collection - it's created if it doesn't already exist
dynamic employeesCollection = storage.Employees;

// Create a document in the Employees collection for John with his email as the document id - the document is created if it doesn't already exist
var employee = employeesCollection.Document("j.doe@example.org");
employee.Name = "John Doe";
employee.Salary = 50000; // John earns $50k/year
employee.Birthdate = new DateTime(1995, 8, 18); // John was born 08/18/1995

// Save the document to the Azure DocumentDB database
employee.Save();
 

The built-in query language make it easy to retrieve data sets

Compose dynamically typed LINQ-queries on the fly at run-time with Slazure's powerful LINQ Provider.

// C# example: Build a document query that return employees that has a salary greater than $40k/year using a dynamic LINQ query filter.
dynamic storage = new QueryableStorage<DynDocument>("mongodb://user:pass@example.org/MongoDBExample");
QueryableCollection<DynDocument> employeesCollection = storage.Employees;
var employeeQuery = employeesCollection
    // Query for salary greater than $40k and born later than early '95.
    .Where("Salary > 40000 and Birthdate >= DateTime(1995,15,3)")
    // Projection and aliasing.
    .Select("new(_id as Email, Birthdate, Name, Timestamp as RegisteredDate)")
    // Order result set by birthdate descending.
    .OrderBy("Birthdate desc")
    // Paging: Skip the first 5 and retrieve only 5.
    .Skip(5).Take(5)
    // Group result set on Birthdate and then on Name.
    .GroupBy("Birthdate", "Name");

// Use a dynamic type so that we can get access to the document's dynamic properties
foreach (dynamic employee in employeeQuery)
{
    // Show some information about the employee
    Console.WriteLine("The employee '{0}' was employed {1} and was born in {2}.",
        employee.Email, employee.RegisteredDate, employee.Birthdate.Year);
}
// C# example: Build a table query that return employees that has a salary greater than $40k/year using a dynamic LINQ query filter.
dynamic storage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true");
QueryableTable<DynEntity> employeesTable = storage.Employees;
var employeeQuery = employeesTable
    // Query for salary greater than $40k and born later than early '95.
    .Where("Salary > 40000 and Birthdate >= DateTime(1995,15,3)")
    // Projection and aliasing.
    .Select("new(PartitionKey as Email, Birthdate, Name, Timestamp as RegisteredDate)")
    // Order result set by birthdate descending.
    .OrderBy("Birthdate desc")
    // Paging: Skip the first 5 and retrieve only 5.
    .Skip(5).Take(5)
    // Group result set on Birthdate and then on Name.
    .GroupBy("Birthdate", "Name");

// Use a dynamic type so that we can get access to the document's dynamic properties
foreach (dynamic employee in employeeQuery)
{
    // Show some information about the employee
    Console.WriteLine("The employee '{0}' was employed {1} and was born in {2}.",
        employee.Email, employee.RegisteredDate, employee.Birthdate.Year);
}
// C# example: Build a document query that return employees that has a salary greater than $40k/year using a dynamic LINQ query filter.
dynamic storage = new QueryableStorage<DynDocument>("URL=https://contoso.documents.azure.com:443/;DBID=DDBExample;TOKEN=VZ+qKPAkl9TtX==");
QueryableCollection<DynDocument> employeesCollection = storage.Employees;
var employeeQuery = employeesCollection
    // Query for salary greater than $40k and born later than early '95.
    .Where("Salary > 40000 and Birthdate >= DateTime(1995,15,3)")
    // Projection and aliasing.
    .Select("new(id as Email, Birthdate, Name, Timestamp as RegisteredDate)")
    // Order result set by birthdate descending.
    .OrderBy("Birthdate desc")
    // Paging: Skip the first 5 and retrieve only 5.
    .Skip(5).Take(5)
    // Group result set on Birthdate and then on Name.
    .GroupBy("Birthdate", "Name");

// Use a dynamic type so that we can get access to the document's dynamic properties
foreach (dynamic employee in employeeQuery)
{
    // Show some information about the employee
    Console.WriteLine("The employee '{0}' was employed {1} and was born in {2}.",
        employee.Email, employee.RegisteredDate, employee.Birthdate.Year);
}
 

Write high-performance queries

The Slazure LINQ Provider's query optimizer builds fast database queries that retrieve only what's requested.

Retrieve only the entity properties you need with query projections rather than the whole entity.

// C# example: Query the data storage for document id and Salary properties only and rename the _id property to "Email".
var employeeQuery = employeesCollection.Where("Salary > 40000")
    .Select("new(_id as Email, Salary)");

// Use a dynamic type so that we can get access the document's dynamic properties
foreach (dynamic employee in employeeQuery)
{
    // Show some information about the employee
    Console.WriteLine("The employee '{0}' earns ${1}/yr.", employee.Email, employee.Salary);
}
// C# example: Query the data storage for PartionKey and Salary properties only and rename the PartionKey property to "Email".
var employeeQuery = employeesTable.Where("Salary > 40000")
    .Select("new(PartitionKey as Email, Salary)");

// Use a dynamic type so that we can get access the entity's dynamic properties
foreach (dynamic employee in employeeQuery)
{
    // Show some information about the employee
    Console.WriteLine("The employee '{0}' earns ${1}/yr.", employee.Email, employee.Salary);
}
// C# example: Query the data storage for document id and Salary properties only and rename the id property to "Email".
var employeeQuery = employeesCollection.Where("Salary > 40000")
    .Select("new(id as Email, Salary)");

// Use a dynamic type so that we can get access the document's dynamic properties
foreach (dynamic employee in employeeQuery)
{
    // Show some information about the employee
    Console.WriteLine("The employee '{0}' earns ${1}/yr.", employee.Email, employee.Salary);
}

Retrieve only a subset of the data set from the data storage rather than the whole set.

// C# example: Query the data storage for only the first five entities in the data set.
var employeeQuery = employeesTable.Where("Salary > 40000").Take(5);

Skip part of the data set rather than reading from the beginning of the set.

// C# example: Skip the first five entities in the data set.
var employeeQuery = employeesTable.Where("Salary > 40000").Skip(5);

Use or merge existing POCO.

using System;
using System.Reflection;
using SysSurge.Slazure.MongoDB;

namespace SysSurge.Slazure.Examples
{
public class Employee
{
    public string _id { get; set; }
    public int SalaryUsd { get; set; }
    public DateTime EmplyedSinceDate { get; set; }
}

public class EmployeePersonal
{
    public DateTime BornDate { get; set; }
    public string WorkLocation { get; set; }
}

public void PocoMergeExample()
{
    // Get a reference to the PocoTest database.
    dynamic storage = new DynStorage("mongodb://localhost/PocoTest");

    // Get a reference to the "TestCustomers" MongoDB document
    dynamic collection = storage.TestEmployees;

    // Create a POCO that hold some information about an employee.
    Employee employee = new Employee();
    employee._id = "Hillary.Doe@example.org"; // Required property.
    employee.SalaryUsd = 65000;
    employee.EmplyedSinceDate = new DateTime(2016, 7, 3);

    // Create an entity using the POCO.
    dynamic entity = collection.Document(employee);

    // Add a property dynamically.
    entity.Position = "HR Manager";

    // Optionally merge other employee data from another POCO, use a predicate to ignore a property.
    EmployeePersonal extraPoco = new EmployeePersonal();
    extraPoco.BornDate = new DateTime(1989, 6, 1);
    extraPoco.WorkLocation = "D.C"; // Later ignored by our predicate.

    // Create a pedicate that ignores the WorkLocation property from extraPoco.
    Func<PropertyInfo, bool> predicate = (p => p.CanRead && p.PropertyType.IsPublic && p.Name != "WorkLocation");

    // Merge extraPoco with document.
    entity.Merge(extraPoco, predicate);

    entity.Save(); // Save the document to MongoDB.
}
}

Use Slazure's dynamic object model API to query the database.

// C# example: How to query for documents using the object model.
dynamic storage = new DynStorage("mongodb://user:pass@example.org/MongoDBExample");

// Get a reference to the Employees document collection
dynamic employeesCollection = storage.Employees;

// Get a reference to an employee document using his/her email as the document _id property
dynamic employee = employeesCollection.Document("j.doe@example.org");

Console.WriteLine("The employee '{0}' salary is {1}.", employee.Name, employee.Salary);
// C# example: How to query for entities using the object model.
dynamic storage = new DynStorage("UseDevelopmentStorage=true");

// Get a reference to the Employees table
dynamic employeesTable = storage.Employees;

// Get a reference to an employee entity using his/her email as the PartitionKey property
dynamic employee = employeesTable.Entity("j.doe@example.org");

Console.WriteLine("The employee '{0}' salary is {1}.", employee.Name, employee.Salary);
// C# example: How to query for documents using the object model.
dynamic storage = new DynStorage("URL=https://contoso.documents.azure.com:443/;DBID=DDBExample;TOKEN=VZ+qKPAkl9TtX==");

// Get a reference to the Employees document collection
dynamic employeesCollection = storage.Employees;

// Get a reference to an employee document using his/her email as the document id property
dynamic employee = employeesCollection.Document("j.doe@example.org");

Console.WriteLine("The employee '{0}' salary is {1}.", employee.Name, employee.Salary);

Slazure's Dynamic Expression API supports Substitution Values through a parameter array.

// C# example: Query the storage for employee that earn less than $60k/yr and that are born before the millennium.
var amount = 60000;
var employeeQuery = employeesTable.Where("Salary > @0 and Timestamp <= @1", amount, new DateTime(2000, 1, 1));

Logical and Additive operators are supported by the expression language.

// C# example: Query the data storage using substitution values.
var firstname = "John";
var surname = " Doe";

// Query for a salary base starting at $30k/yr
var salaryBase = 30000;

// Concatenate strings in query and add $10k/yr as the salary base
var employeeQuery = employeesTable.Where("Name = @0 & @1 and Salary > 10000 + @2", firstname, surname, salaryBase);

Accessible types support method and constructor invocations.

// C# example: Query the data storage using constructor invocations.
var employeeQuery = employeesTable.Where("Timestamp <= DateTime(2000, 1, 1)");