Basic transformations

Assuming that you already know how to create transformers, you will want to know what can be done with them and what projection functions can be created.

Projection function

Transformers core is its projection function. It is a LINQ-based function with the ability to load or include additional documents. Parameters can be also passed to customize the behavior.

Basics

To start, let's create a projection that will return only the FirstName and the LastName from each returned Employee from the Northwind database.

  • first, let's start creating a transformer Employees/FirstAndLastName

public class Employees_FirstAndLastName : AbstractTransformerCreationTask<Employee>

You have probably noticed that we're passing Employee as a generic parameter to AbstractTransformerCreationTask. By doing so, our transformation function will have a strongly-typed syntax.

  • the next step is to create a transformation itself. To do so, we need to set the TransformResults property with our function in parameterless constructor.

public Employees_FirstAndLastName()
{
	TransformResults = employees => from employee in employees
					select new
					{
						FirstName = employee.FirstName,
						LastName = employee.LastName
					};
}
public Employees_FirstAndLastName()
{
	TransformResults = employees => employees
		.Select(employee => new
		{
			FirstName = employee.FirstName, 
			LastName = employee.LastName
		});
}

IList<dynamic> results = session
	.Query<Employee>()
	.TransformWith<Employees_FirstAndLastName, dynamic>()
	.ToList();

Probably dynamic is not the best return type so, obviously, projections to concrete types are supported:

public class Result
{
	public string FirstName { get; set; }

	public string LastName { get; set; }
}

IList<Employees_FirstAndLastName.Result> results = session
	.Query<Employee>()
	.TransformWith<Employees_FirstAndLastName, Employees_FirstAndLastName.Result>()
	.ToList();

Our final transformer looks like this:

public class Employees_FirstAndLastName : AbstractTransformerCreationTask<Employee>
{
	public class Result
	{
		public string FirstName { get; set; }

		public string LastName { get; set; }
	}

	public Employees_FirstAndLastName()
	{
		TransformResults = employees => from employee in employees
						select new
						{
							FirstName = employee.FirstName,
							LastName = employee.LastName
						};
	}
}

Important

Before moving further, please note that property values of the objects passed to the projection function (in our example we are passing employees) are taken from the stored index fields, if present, otherwise they are loaded from a database.

Example

If we would store the FirstName and the LastName in the index that was queried, then the above transformer would use the values from index directly, without loading them from a database.

Projecting a single property

You do not have to create a new objects each time: when only single property is required, all you need to do is select that property:

public class Employees_FirstName : AbstractTransformerCreationTask<Employee>
{
	public Employees_FirstName()
	{
		TransformResults = employees => from employee in employees select employee.FirstName;
	}
}

IList<string> results = session
	.Query<Employee>()
	.TransformWith<Employees_FirstName, string>()
	.ToList();

Projecting a complex property

When your documents contain nested objects and you want to return only those, then the projection can look as follows:

public class Employees_Address : AbstractTransformerCreationTask<Employee>
{
	public Employees_Address()
	{
		TransformResults = employees => from employee in employees select employee.Address;
	}
}

IList<Address> results = session
	.Query<Employee>()
	.TransformWith<Employees_Address, Address>()
	.ToList();