Consider I have a parent, child relationship class and mapping. I am using NHibernate to read the object from the database, and intended to use WCF to send the object across the wire.
[DataContract]
, it cannot be serialized as the property is lazy load proxy instead of real known type.lazy=false
or lazy=true
doesn't work. Former will eagerly fetch all the relationships, latter will create a proxy. But I want nothing instead - a null
would be the best.null
for those references that I don't want to fetch. A null, but not just a proxy. This will makes WCF happy, and waste less time to have a lazy-load proxy constructed.GetObjectToSerialize
, I never observe an proxy being passed through GetObjectToSerialize
, leaving no chance to un-proxy it.After reading the comments, more surfing on the Internet...
It seems to me that DTO would shift major part of the computation to the server side. But for the project I am working on, 50% of time the client is "smarter" than the server and the server is more like a data store with validation and verification. Though I agree the server is not exactly dumb - I have to decide when to fetch the extra references already, and DTO will make this very explicit.
Maybe I should just take the pain. I didn't know http://automapper.codeplex.com/ before, this motivates me a little more to take the pain.
On the other hand, I found http://trentacular.com/2009/08/how-to-use-nhibernate-lazy-initializing-proxies-with-web-services-or-wcf/, which seems to be working with IDataContractSurrogate.GetObjectToSerialize
.
Was getting the same issue with WCF-Silverlight transferring of DTO/Entities. I use following code which works fine:
Fluent NHibernate:
References(c => c.DataSource)
.Column("DataSourceId")
.Cascade.None()
.Not.LazyLoad();
HasManyToMany(c => c.Categories)
.Table("Categories")
.ParentKeyColumn("ItemId")
.ChildKeyColumn("CategoryId")
.Not.LazyLoad()
.Cascade.None()
.Inverse();
XML:
<many-to-one name="DataSource" column="DataSourceId" lazy="false" cascade="none" />
Hope this'll work for you!
I have run into similar issues with performance, what I did instead was preload the information I want by using an explicit call to the DB using a DetachedCriteria.
So similar to what you are doing I would probably do something like this.
public DetachedCriteria BuildMyCriteria()
{
var criteria = DetachedCriteria.For<ParentClass>();
criteria.CreateCriteria("this.ChildClass", "Child Class").SetFetchMode("this.ChildClass", FetchMode.Eager);
criteria.Add(Restrictions.IsNotNull("ChildClass.Property");
return criteria;
}
Then from my facade, I would get those entities with the properties that do not have null attributes on the child property
var myClasses = _repository.ExecuteDetachedCriteria<ParentClass>(BuildMyCriteria);
Then I would have all ParentClass entities that have a null property.
So instead of taking a hit by constantly asking the DB for info, I store it in memory so it is ready for me to use.
This is just an alternative solution to DTOs, good luck :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With