Say that I've got two database tables: Order and OrderLine.
According to this it is considered good practise to create copies of the database models and use them rather than the database models.
So you typically see converter methods like this.
public OrderModel ToOrderModel(Order order)
{
return new OrderModel
{
OrderID = order.OrderID,
Customer = order.CustomerName,
OrderLines = order.OrderLines
};
}
public OrderLineModel ToOrderLineModel(OrderLine orderLine)
{
return new OrderLineModel
{
OrderLineID = orderLine.OrderLineID,
Quantity = orderLine.Quantity,
Product = orderLine.ProductName,
Order = orderLine.Order
};
}
The trouble with this, in my opinion, is:
- The
OrderLines
property in anOrderModel
is a list of typeOrderLine
rather thanOrderLineModel
. - The
Order
property in anOrderLineModel
is of typeOrder
rather thanOrderModel
.
I've found two solutions to this but both have their limitations and I'm hoping somebody will be able to suggest a better way.
Solution 1
This solution works but it only works in "LINQ to Objects" and not in "LINQ to Entities". It's also a little bit over-complicated.
public OrderModel ToOrderModel(Order order)
{
return ToOrderModel(order, null);
}
private OrderModel ToOrderModel(Order order, List<OrderLineModel> orderLines )
{
//Creating model early so that we have a reference to pass later on
var orderModel = new OrderModel();
orderModel = new OrderModel()
{
OrderID = order.OrderID,
Customer = order.CustomerName,
OrderLines = orderLines ?? order.Lines.ToList().Select(x => ToOrderLineModel(x, orderModel))
};
}
public OrderLineModel ToOrderLineModel(OrderLine orderLine)
{
return ToOrderLineModel(orderLine, null);
}
private OrderLineModel ToOrderLineModel(OrderLine orderLine, OrderModel orderModel)
{
//Creating model early so that we have a reference to pass later on
var orderLineModel = new OrderLineModel();
return new OrderLineModel
{
OrderLineID = orderLine.OrderLineID,
Quantity = orderLine.Quantity,
Product = orderLine.ProductName,
Order = orderModel ?? ToOrderModel(orderLine.OrderModel, orderLineModel),
};
}
Solution 2
This solution makes use of LINQKit and works in "LINQ To Entities". The only problem is that I have to choose between either:
- The
OrderLines
property in anOrderModel
being a list ofOrderLineModel
. - The
Order
property in anOrderLineModel
having the type ofOrderModel
.
public static Expression<Func<Order, OrderModel>> ToOrderModel =
order => new OrderModel()
{
OrderID = order.OrderID,
Customer = order.CustomerName,
Lines = order.OrderLines.Select(orderLine => ToJournalLineModel.Invoke(orderLine)),
};
public static Expression<Func<OrderLine, OrderLineModel>> ToOrderLineModel =
orderLine => new OrderLineModel()
{
OrderLineID = orderLine.OrderLineID,
Quantity = orderLine.Quantity,
Product = orderLine.ProductName,
//Sadly we can't add an OrderModel here :(
};
//example usage
var orderModels = dbContext.Orders.AsExpandable().Select(ToOrderModel);
Does anyone have any suggestions for me?
Thank you in advance