I use Raven to store orders. In the order document I want all the original product details for tracking purposes.
The product objects are basically a proxy for an external object. When I read back orders I want them in a simple View object rather in their original form.
In the index' TransformResult the Order is converted into an anonymous type, when I already have a type for OrderViewModel. And why do I need a index at all?
public class Order
{
public Guid Guid;
public IEnumerable<OrderRow> OrderRows { get; set; }
}
public class OrderViewModel
{
public Guid Guid;
public IEnumerable<OrderRowViewModel> OrderRows { get; set; }
}
public class OrderRow
{
public IProduct Product;
}
public class OrderRowViewModel
{
public ProductViewModel Product;
}
public interface IProduct
{
string DisplayName { get; }
}
public class VeryComplicatedProductInstance : IProduct
{
public string DisplayName { get { return "Product Name"; } }
}
public class ProductViewModel
{
public string DisplayName { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var documentStore = new DocumentStore { Url = "http://localhost:99", DefaultDatabase = "test" }; documentStore.Initialize();
IndexCreation.CreateIndexes(typeof(Order_ById).Assembly, documentStore);
var orderId = Guid.NewGuid();
var order = new Order
{
Guid = orderId,
OrderRows = new[]
{
new OrderRow {Product = new VeryComplicatedProductInstance()}
}
};
using (var session = documentStore.OpenSession())
{
session.Store(order, order.Guid.ToString());
session.SaveChanges();
}
OrderViewModel loadedOrder;
using (var session = documentStore.OpenSession())
{
loadedOrder = session.Query<Order, Order_ById>()
.Where(o => o.Guid == orderId)
.OfType<OrderViewModel>()
.FirstOrDefault();
}
Assert.IsNotNull(loadedOrder);
Assert.IsNotInstanceOfType(loadedOrder.OrderRows.First().Product, typeof(VeryComplicatedProductInstance));
Assert.IsInstanceOfType(loadedOrder.OrderRows.First().Product, typeof(ProductViewModel));
Assert.AreEqual("Product Name", loadedOrder.OrderRows.First().Product.DisplayName);
}
}
public class Order_ById: AbstractIndexCreationTask<Order>
{
public Order_ById()
{
Map = orders => from order in orders
select new { order.Guid, order.OrderRows};
TransformResults = (database, results) => from order in results
select new
{
order.Guid,
OrderRows = order.OrderRows.Select(or=>new
{
Product = new {
DisplayName = or.Product.DisplayName
}
})
};
}
}