TransformResults

If you want to do a client side results transformation in most cases it will be enough to you use standard Linq Select method. However if your intention is to create a bit more complex projection then TransformResults customization method might be useful. An advantage of this approach is that you have an access to the executed index query and the collection of all returned results.

In order to use this method you have to Customize your query as is in the example presented below.

Example

Let's assume that we have the following classes:

public class ProductItem
{
	public string Id { get; set; }
	public string WarehouseId { get; set; }
	public string Name { get; set; }
	public string Manufacturer { get; set; }
	public string Description { get; set; }
	public double Price { get; set; }
}
public class ProductItemViewModel
{
	public string Name { get; set; }
	public string Description { get; set; }
	public double Price { get; set; }
}
public class Warehouse
{
	public string Id { get; set; }
	public IList<ProductItemViewModel> Products { get; set; }
	public double AverageProductPrice { get; set; }
}

and an index defined as follow:

public class Product_ById : AbstractIndexCreationTask<ProductItem>
{
	public Product_ById()
	{
		Map = products => from product in products
						  select new
						  {
							  product.Id
						  };
	}
}

To transform the query results that are Products into Warehouses you can use the code:

var warehouses = session.Query<dynamic, Product_ById>()
	.Customize(x => x.TransformResults((query, results) =>
		results.Cast<dynamic>().GroupBy(p => p.WarehouseId).Select(g =>
		{
			double count = 0;
			int totalSum = 0;

			var products = g.Select(product =>
			{
				count++;
				totalSum += product.Price;
				return new ProductItemViewModel
						   {
							   Name = product.Name,
							   Description = product.Description
						   };
			}).ToList();

			return new Warehouse()
					   {
						   Id = g.Key,
						   Products = products,
						   AverageProductPrice = totalSum / count,
					   };
		}))).ToList();