Not sure if I'm following entirely, but my approach to exposing collections
is to make the getter an IEnumerable:
public class Foo
{
private List<Bar> _bars { get; set; }
public IEnumerable<Bar> Bars
{
get { return _bars; }
}
}
Then I map this using an access strategy:
public void Override(AutoMapping<Foo> mapping)
{
mapping.HasMany(x => x.Bars)
.Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
}
On Sat, Jan 30, 2010 at 4:20 AM, TheNephalim <[email protected]>wrote:
> I'm definitely going to look into the other strategies that you
> mentioned.
>
> One that I found, and seems to work, is the wrapper strategy that you
> alluded to in item number 4. I created a private property that is
> revealed in the mapping and is accessed using the wrapper in a public
> property. When I tested two other properties that I had implemented
> in this fashion, NHibernate determined that the collections were not
> initialized using the assert that I mentioned in my previous posting
> and only generated SQL if I directly accessed the collection directly,
> i.e. User.Phones.Count.
>
> Thank you for your response and confirming what I was thinking as well
> as giving me some other avenues to pursue.
>
> -Robert Eberhart
>
> On Jan 29, 11:54 am, Hudson Akridge <[email protected]> wrote:
> > You may want to toss your question over to the NHUsers google group, but
> > I'll give you my feedback for as much as It'll help ;)
> >
> > is this a trade off wherein we sacrifice encapsulation for performance
> >
> > This. As far as I'm able to gleen, that is the correct assumption to
> make.
> > There are ways around this.
> > 1.) Don't access the collection unless you absolutely need it
> > 2.) Look into doing Join Fetch's during your queries when you get the
> data
> > back if you know you're going to be using that collection as a result of
> the
> > query.
> > 3.) Look into batch or subselect fetching, this is a good loading
> strategy
> > imo
> > 4.) Look into lazy=extra. This allows you to do counts, contains, and a
> few
> > other common collection statements without loading the collection. You
> will
> > still have to access the backing collection, but you can write a wrapper
> in
> > your model. For example:
> > public virtual int FastCountOfLogins()
> > {
> > return _logins.Count();
> >
> > }
> >
> > That will keep your collection lazy loaded until you actually need to do
> > something like a for each and iterate over it.
> > 5.) Grab nhprofiler. This is one of the single best tools for finding
> bottle
> > necks in your application.
> >
> > On Fri, Jan 29, 2010 at 8:10 AM, TheNephalim <[email protected]
> >wrote:
> >
> >
> >
> > > I have several issues that I'm working on, because I'm a newbie at
> > > this, and wanted to address the one that I "solved" first.
> >
> > > The problem was that I was noticing that all of my collections were
> > > not loading lazily, no matter what I did to mark them as such. It
> > > then dawned on me that the problem was the way I was returning the
> > > collection.
> >
> > > For example,
> >
> > > public virtual IList<Login> Logins {
> > > get { return new List<Login>(_logins).AsReadOnly(); }
> > > protected set { _logins = value; }
> > > }
> >
> > > I did it this way because if you just return _logins, you're actually
> > > returning a reference to the private variable which violates
> > > encapsulation and the whole reason for marking it private in the first
> > > place.
> >
> > > The problem is that the parent object, User, is a proxy. Any time
> > > that that parent object was accessed, for example, to set
> > > User.LastName, a query for each of the collections was fired. The
> > > solution was to change the property to this:
> >
> > > public virtual IList<Login> Logins {
> > > get { return _logins; }
> > > protected set { _logins = value; }
> > > }
> >
> > > I have run several tests in NUnit and watched the queries coming back
> > > to know that this is what's happening. Additionally, I used the
> > > following:
> >
> > > Assert.IsFalse(NHibernateUtil.IsInitialized(testUser.Logins));
> >
> > > It passes for the second property implementation and not the first.
> >
> > > The question I have is this: Is there a way to encapsulate the
> > > private variable but still have a proxy for lazy loading, or is this a
> > > trade off wherein we sacrifice encapsulation for performance?
> >
> > > Any help you can offer is appreciated.
> >
> > > Sincerely,
> > > Robert Eberhart
> >
> > > --
> > > You received this message because you are subscribed to the Google
> Groups
> > > "Fluent NHibernate" group.
> > > To post to this group, send email to
> [email protected].
> > > To unsubscribe from this group, send email to
> > > [email protected]<fluent-nhibernate%[email protected]>
> <fluent-nhibernate%[email protected]<fluent-nhibernate%[email protected]>
> >
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/fluent-nhibernate?hl=en.
> >
> > --
> > - Hudsonhttp://www.bestguesstheory.comhttp://twitter.com/HudsonAkridge
>
> --
> You received this message because you are subscribed to the Google Groups
> "Fluent NHibernate" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<fluent-nhibernate%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/fluent-nhibernate?hl=en.
>
>
--
You received this message because you are subscribed to the Google Groups
"Fluent NHibernate" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/fluent-nhibernate?hl=en.