I have a schema with Project
objects. Each Project has an owner, and an additional collection of SharePermission
objects detailing other users that can also access the Project. SharePermissions point to a more detailed user object of type IdentityUser
In this case, I load an IEnumerable
of Projects
using the method:
/// <summary>
/// Gets a collection of projects that a user id has access to view.
/// </summary>
public static IEnumerable<Project> GetVisibleByUserFuture(ISession session, int userId)
{
Project p = null;
ProjectShare s = null;
IdentityUser u = null;
return session.QueryOver<Project>(() => p)
.Left.JoinAlias(() => p.SharePermissions
, () => s // Only join when we are not owner
, Restrictions.On(() => p.OwnerId).Not.IsIn(new [] { userId }))
.Left.JoinAlias(() => s.User, () => u)
.Where(() => s.User.UserId == userId || p.OwnerId == userId)
.Future();
}
You will notice that the SharePermissions
part had a restriction on the join so only part of that collection is loaded.
Later on I want to pick a single Project
from that previously loaded IEnumerable collection and load the full SharePermissions
collection without restriction.
I am not entirely sure how I'm meant to do that.
Do I just load a whole new Project
object again?
Or can I re-use the existing Project
object and somehow tell NH to fully populate the SharePermissions collection?
Solution in this case would be session.Refresh(project)
. As documented here:
It is possible to re-load an object and all its collections at any time, using the Refresh() method. This is useful when database triggers are used to initialize some of the properties of the object.
...
session.Refresh(project);
But I would suggest to change the query. Select just a root entity Project, use subquery to filter it, apply batch fetching for collection loading
check these links for batch fetching and subquery examples: