Yeah we don't have support for lazy=extra yet. You could say that I have my
lazy attribute set to extra - I want someone else to submit the patch!

On Tue, Feb 2, 2010 at 3:39 PM, Robert Eberhart
<[email protected]>wrote:

> I'm intrigued about lazy=extra but tried to research it and couldn't find
> any information. If I'm correct, HasMany, HasManyToMany, etc. don't have
> SetAttribute like earlier versions of FNH. Do you have any links you could
> point me to?
>
>
> On Feb 1, 2010, at 8:17 PM, Hudson Akridge <[email protected]>
> wrote:
>
> Your thoughts on why to just expose it out as an ienumerable make sense.
> There's positives and negatives to both. Wrapping it in a ReadOnlyCollection
> initializes it, as well as prevents you from ever being able to take
> advantage of lazy=extra.
>
> On Mon, Feb 1, 2010 at 6:37 PM, Paul Batum < <[email protected]>
> [email protected]> wrote:
>
>> Yes, sorry, there was an error in my code. You can map the member as
>> either a field or a property, but you have to use the appropriate
>> access mechanism. ReadOnlyPropertyThroughCamelCaseField tells
>> NHibernate to use the mapped property when getting the value, and to
>> look for a field with camel case naming and to use that when setting
>> the value. If the underlying member is an autoproperty, then it will
>> fail to find a matching field.
>>
>>
>> On Tue, Feb 2, 2010 at 8:17 AM, TheNephalim < <[email protected]>
>> [email protected]> wrote:
>> >
>> > I implemented what Paul suggested, although I had to do it slightly
>> > differently and I'm not sure why.
>> >
>> > public class User {
>> >
>> >        private IList<Phone> _phones;
>> >
>> >        /// <summary>
>> >        /// A list of contact phone numbers.
>> >        /// </summary>
>> >        public virtual IEnumerable<Phone> Phones {
>> >            get { return _phones; }
>> >        }
>> >
>> >        public virtual void AddPhone(Phone phone) {
>> >            Check.Require(phone != null, "Phone cannot be left
>> > undefined.");
>> >
>> >            if (!_phones.Contains(phone)) {
>> >                _phones.Add(phone);
>> >            }
>> >        }
>> > }
>> >
>> > The mapping for the property is:
>> >
>> >            HasMany<Phone>(x => x.Phones)
>> >                .Access.ReadOnlyPropertyThroughCamelCaseField
>> > (Prefix.Underscore)
>> >                .Table("Phone")
>> >                .KeyColumn("UserId")
>> >                .Cascade.All().Inverse()
>> >                .AsBag();
>> >
>> > If I added the get/set to the private IList<Phone> _phones, I received
>> > an error indicating that it couldn't find the field "_phones".
>> > However, now that I'm thinking about it, that might make sense because
>> > having the get/set would indicate a propert and not a field.  I'm not
>> > sure if the the Property access strategy would work and I believe that
>> > you would also have to use the Reveal.Property<Entity>("Property")
>> > method.  I also think that you would probably have to rename the
>> > property to something like m_Phones.  I have not have too much luck
>> > using the Reveal.Property method; sometimes it seems to work and other
>> > times....not.
>> >
>> > I also had to change the List<T> to IList<T>, otherwise to access
>> > contains I would have to access it through the public IEnumerable
>> > Phones instead of the private variable.  To add a new value, I would
>> > need to access the private variable, but would receive an error
>> > indicating an index out of range exception.  Changing the collection
>> > from List<T> to IList<T> seems to have remedied that problem.
>> >
>> > I'm going to continue testing to make sure that everything is cool.
>> > It appears, though, that I have reached something that I can
>> > definitely live with.
>> >
>> > Thanks again,
>> > Robert
>> >
>> > On Jan 30, 6:53 pm, Paul Batum <[email protected]> wrote:
>> > > I'm familiar with what AsReadOnly does - it used to be my preferred
>> > > approach! Until I realised that compile time errors are preferable to
>> > > runtime errors :)
>> > >
>> > > You could argue that a combination of both techniques is best - that
>> way
>> > > you're still exposing a readonly interface and preventing the casting
>> > > problem. But if my developers are casting back to lists instead of
>> using the
>> > > appropriate methods (AddXXX, RemoveXXX), I've got bigger problems. I
>> try to
>> > > expose a public interface that makes the wrong things hard and the
>> right
>> > > things easy - I rarely go further than that. YMMV.
>> > >
>> > > On Sun, Jan 31, 2010 at 2:27 AM, Hudson Akridge <
>> [email protected]>wrote:
>> > >
>> > > > You can make the getter an IEnumerable for your property wrapper,
>> but you
>> > > > can still cast it back to a list and then make modifications to it.
>> > > > .AsReadOnly() wraps it in a new read only collection that throws
>> exceptions
>> > > > whenever .Add/.Remove or any other collection modification methods
>> are
>> > > > attempted to be called. Otherwise all you're doing it providing a
>> read only
>> > > > interface, but not actually enforcing it.
>> > >
>> > > > Example:
>> > > > public class Person
>> > > >     {
>> > > >         public Person()
>> > > >         {
>> > > >             _test = new List<string>();
>> > > >         }
>> > > >         private readonly IList<string> _test;
>> > > >         public IEnumerable<string> Test
>> > > >         {
>> > > >             get { return _test; }
>> > > >         }
>> > > >     }
>> > >
>> > > > //Usage
>> > > >             var tmp = new Person();
>> > > >             var tmp2 = tmp.Test as List<string>;
>> > > >             tmp2.Add("test");
>> > >
>> > > > tmp2 will have a count of 1 after this, and "test" will have been
>> added.
>> > > > This is typically not what you'd want a user of your model to be
>> able to do.
>> > >
>> > > > On Fri, Jan 29, 2010 at 11:23 PM, Paul Batum <[email protected]>
>> wrote:
>> > >
>> > > >> 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]>
>> [email protected].
>> > > >>> > > To unsubscribe from this group, send email to
>> > > >>> > > <fluent-nhibernate%[email protected]>
>> [email protected]<
>> fluent-nhibernate%[email protected]<fluent-nhibernate%[email protected]>
>> >
>> > > >>> <fluent-nhibernate%[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>
>> http://groups.google.com/group/fluent-nhibernate?hl=en.
>> > >
>> > > >>> > --
>> > > >>> > - 
>> > > >>> > Hudsonhttp://www.bestguesstheory.comhttp://<http://twitter.com/HudsonAkridge>
>> 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]>[email protected].
>> > > >>> To unsubscribe from this group, send email to
>> > > >>> <fluent-nhibernate%[email protected]>
>> [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>
>> 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]>[email protected].
>> > > >> To unsubscribe from this group, send email to
>> > > >> <fluent-nhibernate%[email protected]>
>> [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>
>> http://groups.google.com/group/fluent-nhibernate?hl=en.
>> > >
>> > > > --
>> > > > - Hudson
>> > > > <http://www.bestguesstheory.com>http://www.bestguesstheory.com
>> > > > <http://twitter.com/HudsonAkridge>http://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]>[email protected].
>> > > > To unsubscribe from this group, send email to
>> > > > <fluent-nhibernate%[email protected]>
>> [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>
>> 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]>[email protected].
>> > To unsubscribe from this group, send email to
>> <fluent-nhibernate%[email protected]>
>> [email protected].
>> > For more options, visit this group at
>> <http://groups.google.com/group/fluent-nhibernate?hl=en>
>> 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]>
>> [email protected].
>> To unsubscribe from this group, send email to
>> <fluent-nhibernate%[email protected]>
>> [email protected].
>> For more options, visit this group at
>> <http://groups.google.com/group/fluent-nhibernate?hl=en>
>> http://groups.google.com/group/fluent-nhibernate?hl=en.
>>
>>
>
>
> --
> - Hudson
> <http://www.bestguesstheory.com>http://www.bestguesstheory.com
> <http://twitter.com/HudsonAkridge>http://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].
> 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]<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.

Reply via email to