Get Nhibernate entity and complete it from a web service
let's say that i have an order system. each "Order" references a "Customer" Object. when i fill the orders list in Data Access Layer, the customer object should be brought from a Customer Web Service "WCF". so i didn't map the Customer property in the Order mapping class,
Id(o => o.OrderID).GeneratedBy.Identity();
//References(o => o.Customer).Not.Nullable().Column("CustomerID");
HasMany(o => o.Details).KeyColumn("OrderID").Cascade.AllDeleteOrphan();
Map(c => c.CustomerID).Not.Nullable();
and asked the nhibernate session to get me the orders list. and tried to loop on every order in the list to fill it's customer property, doe's any body have a good idea for this ????
IList<Order> lst = Session.Create开发者_如何转开发Criteria<Order>().List<Order>();
foreach (Order order in lst)
order.Customer = serviceProxy.GetCustomerByID(order.CustomerID);
So you're saying that you hit your WCF, for Order list of 50, 50 times. Not so good.
You should do this:
var customers = serviceProxy.GetCustomersForIDs(lst.Select(x => x.CustomerID).Distinct()); //one hit to WCF
foreach(var order in lst)
order.Customer = customers.Single(x => x.ID == order.CustomerID);
That is for performance vise.
The other thing that you can do and be fancy (and not so performace oriented, but exactly the same performace as your sample):
modify property Customer as this:
private customer;
public virtual Customer
{
get
{
if(customer == null)
customer = serviceProxy.GetCustomerByID(this.CustomerID);
return customer;
}
}
Where your order should have a reference to serviceProxy.
If you really want to do this transparently, try implementing a custom tuplizer (and associated things). Take a look at this article, it implements a remote lazy loader for Java Hibernate, however the general concepts apply equally to NHibernate since it has the same overall design (tuplizers, lazy initializers, proxy factory, etc).
精彩评论