Is .Load<T> the only way to get Parent Id in a query?

71 views
Skip to first unread message

rhartzog

unread,
Jun 27, 2011, 4:17:04 PM6/27/11
to nhusers
Is there a way to access the Parent Id if you lazy load the parent and
don't want to or need to use load? I just want to print the value of
the parent id property but not fetch the entire object.

Francois Ward

unread,
Jun 27, 2011, 4:22:59 PM6/27/11
to nhu...@googlegroups.com
Someone correct me if I'm wrong, but I'm pretty sure if you have an Object A with a property B representing its parent, and you do:


Assuming Parent is an instance of B which is lazy loaded, so it is in proxy-form, accessing the Id will not trigger a server roundtrip.

-Francois


--
You received this message because you are subscribed to the Google Groups "nhusers" group.
To post to this group, send email to nhu...@googlegroups.com.
To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.


rhartzog

unread,
Jun 27, 2011, 4:37:05 PM6/27/11
to nhusers
I thought that also, but it is kicking a session closed error (in this
case manually managing sessions) so I am unable to just use the Id of
the parent. Any ideas?

Francois Ward

unread,
Jun 27, 2011, 4:43:14 PM6/27/11
to nhu...@googlegroups.com
Do you have a mapping around? It seems pretty illogical otherwise. You load Object A, and Parent is a proxy... As opposed to using .Load<>, which returns...a proxy. Both should behave the same way.

rhartzog

unread,
Jun 27, 2011, 5:03:38 PM6/27/11
to nhusers
It is mapped as a simple many-to-one, is that what you are asking?

<many-to-one name="Parent" cascade="save-update" column="ParentId" not-
null="true" />

Tomek Pluskiewicz

unread,
Jun 28, 2011, 4:20:55 AM6/28/11
to nhu...@googlegroups.com
If you are getting an exception about closed session, it is probably where the problem is.

Could you say how you manage your session?

In any case I'm surpirised you would still need the session to get parent's id but it seems logical from what you said

Jason Meckley

unread,
Jun 28, 2011, 8:11:20 AM6/28/11
to nhu...@googlegroups.com
you mentioned a session closed error. are you trying to access the value like

using(var session = factory.OpenSession())
{
   var entity = session.Get<Entity>(id);
   return entity.Parent.Id;
}
or
using(var session = factory.OpenSession())
{
   var entity = session.Get<Entity>(id);
}
return entity.Parent.Id;

the first approach will work, then second would not. the scope of the session matters.

Ramon Smits

unread,
Jun 28, 2011, 8:41:57 AM6/28/11
to nhu...@googlegroups.com

I think you ment .Load<T> as I would expect your code to work but when using Load<T> it would not.

--
You received this message because you are subscribed to the Google Groups "nhusers" group.
To view this discussion on the web visit https://groups.google.com/d/msg/nhusers/-/J4bYf3brY1UJ.

To post to this group, send email to nhu...@googlegroups.com.
To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.



--
Ramon

rhartzog

unread,
Jun 28, 2011, 9:02:12 AM6/28/11
to nhusers
The session is being managed in another layer. So if I call down to
_subService.GetChildStuff(childId) and retrieve the child, it calls,
gets the info, eagerly loading some of the other child relationships
and closes session. I don't want to add yet another join to the query
when all I need is the parent id and nothing else at this point. Once
I have the child I would like to be able to print the parent id to
screen with Child.Parent.Id without having to go back to the db for
the id itself.

The session is indeed closed at the point I call the parent id, but
that is intended and expected behavior. I know I can go back and
hydrate the parent object with another call, but I would prefer not to
do that if possible.

On Jun 28, 7:41 am, Ramon Smits <ramon.sm...@gmail.com> wrote:
> I think you ment .Load<T> as I would expect your code to work but when using
> Load<T> it would not.
>

rhartzog

unread,
Jun 28, 2011, 10:27:54 AM6/28/11
to nhusers
@Jason: The second approach. The session will have been closed/out of
scope when called. In nhprof the query returns the Id of the parent,
so I was hoping it would not be wrapped up in the scope of the session
for that property, only if I needed other properties on the parent. I
guess the Id is wrapped up in the proxy since the object doesn't have
a parentid property, but simply a reference to the parent object.

Jason Meckley

unread,
Jun 28, 2011, 11:47:16 AM6/28/11
to nhu...@googlegroups.com
 correct. as i suspected, the session does not align with the unit of work. you either need to build up the result before the session closes, or change the scope of the session so it's still available when you call entity.Parent.Id.

fkne...@gmail.com

unread,
Jun 28, 2011, 11:52:36 AM6/28/11
to nhu...@googlegroups.com
I would be creating a DTO or DataContract or something to return all the data you need when you are returning from the service layer.

Does your service layer return domain objects directly?

It would be very easy to return a new type with everything your needed.



On , Jason Meckley <jasonm...@gmail.com> wrote:
>  correct. as i suspected, the session does not align with the unit of work. you either need to build up the result before the session closes, or change the scope of the session so it's still available when you call entity.Parent.Id.
>
>
>
>
>
> --
>
> You received this message because you are subscribed to the Google Groups "nhusers" group.
>
> To view this discussion on the web visit https://groups.google.com/d/msg/nhusers/-/oWkmb1m-F9MJ.

Jason Meckley

unread,
Jun 28, 2011, 12:50:04 PM6/28/11
to nhu...@googlegroups.com
+1 this is the approach I use and it avoids so many pitfalls.maintenance and session scope are simplified the only downside (if you consider it one) is the number of objects in the code increases.

Nexus

unread,
Jun 29, 2011, 10:45:29 AM6/29/11
to nhusers
Jason,

Why should the second trigger lazy loading, besides from the fact if
you use not-found=ignore or property-ref attribute ?

rhartzog

unread,
Jun 29, 2011, 11:07:06 AM6/29/11
to nhusers
We have a little bit of a catch22 going on with this one. There is a
function to build up the view model, but the view models on this
project have a ton of data that they need. Typically I would follow a
single call, compose the VM and return to controller for consumption.
This project calls down into a service for calls such as for
MediaItems, ContentBlocks, etc. Some of the aggregate roots have
multiple value objects needed for a single screen. Because many of
these calls can be in parallel we have made it so. So you may get:

Parrallel.Invoke(
() => _mediaService.GetStuff(),
() => _contentService.GetStuff()
);

//Compose the ViewModel here and return

Alright, thanks for the input guys, might have to rethink some of this
and figure out which negatives are the ones we can live with while
still meeting the reqs.

Jason Meckley

unread,
Jun 29, 2011, 12:20:08 PM6/29/11
to nhu...@googlegroups.com
@Nexus are referring to why entity.Parent.Id needs to be called within the scope of the session?
the proxy has knowledge about the session. if you try to access any part of proxied object outside of the session it will throw session closed. I'm not sure what the results are if you disconnect the entity from the session prior to accessing the referenced entity. i would assume the referenced entity would report null since you didn't access it.

btw: not-found and property-ref don't apply to this thread.

Nexus

unread,
Jun 30, 2011, 6:44:43 AM6/30/11
to nhusers
Again i really think that getting the id of the parent should not
trigger lazy load, as confirmed in BasicLazyInitializer Code :

public virtual object Invoke(MethodInfo method, object[] args, object
proxy)
{
string methodName = method.Name;
int paramCount = method.GetParameters().Length;

if (paramCount == 0)
{
if (!overridesEquals && methodName == "GetHashCode")
{
return IdentityEqualityComparer.GetHashCode(proxy);
}
else if (IsUninitialized &&
IsEqualToIdentifierMethod(method)) !!!!!!!!!!!!
HERE!!!!!!!!!!!!!!!!!!!
{
return Identifier;
}

So i think something else is going on ?

Jason Meckley

unread,
Jun 30, 2011, 11:41:09 AM6/30/11
to nhu...@googlegroups.com
the next thing to figure out is when the proxy code is triggered. if it's triggered when you call entity.parent.id then a session closed exception makes sense, if it's created when the root entity is hydrated then i'm at a loss.

however with all the time invested in this thread. I would either access the property within the session scope before closing the session, or eager load the parent entity to resolve the issue. In either case it doesn't work the way you expect/want it to.


Reply all
Reply to author
Forward
0 new messages