public static void VisitNodes(object obj, ISession session, EntityNodeInfo includeChildNodes) { if (obj is null || includeChildNodes?.Children == null) { return; } if (obj is IEnumerable) { foreach (var o in (IEnumerable)obj) { VisitNodes(o, session, includeChildNodes); } return; } var objType = obj.GetType(); bool isInitialized = false; foreach (var childExpr in includeChildNodes.Children) { var childProp = objType.GetProperty(childExpr.Name); var childValue = childProp.GetValue(obj); VisitNodes(childValue, session, childExpr); isInitialized = true; } if (!isInitialized) { NHibernateUtil.Initialize(obj); } }
private void PopulateChildrenCriteria(EntityNodeInfo nodeInfo, ICriteria rootCriteria, ICriteria parentCriteria, ref bool rootHasList, List <ICriteria> childCriterias) { if (nodeInfo == null) { return; } if (nodeInfo.Level > 0) //it's not the root node { if (nodeInfo.IsList) { if (rootHasList) { if (nodeInfo.Level == 1) //create new criteria { parentCriteria = rootCriteria.CreateCriteria(nodeInfo.PathName, JoinType.LeftOuterJoin); childCriterias.Add(parentCriteria); } else //batch fetch should be faster { return; } } else { parentCriteria.Fetch(SelectMode.Fetch, nodeInfo.PathName); rootHasList = true; } } else { parentCriteria.Fetch(SelectMode.Fetch, nodeInfo.PathName); } } foreach (var childInfo in nodeInfo.Children) { PopulateChildrenCriteria(childInfo, rootCriteria, parentCriteria, ref rootHasList, childCriterias); } }
public IEntityListWrapper <T> Include(params Expression <Func <T, object> >[] includeChildNodes) { _childNodesInfo = NHUnitHelper.GetExpressionTreeInfo <T>(includeChildNodes, _childNodesInfo ?? new EntityNodeInfo(), true); return(this); }
public ISingleEntityWrapper <T> Include(params Expression <Func <T, object> >[] includeChildNodes) { CheckDeferred(); _childNodesInfo = NHUnitHelper.GetExpressionTreeInfo <T>(includeChildNodes, _childNodesInfo ?? new EntityNodeInfo(), true); return(this); }
public static EntityNodeInfo GetExpressionTreeInfo <T>(Expression <Func <T, object> >[] includeChildNodes, EntityNodeInfo rootNode, bool includeParent = false) { foreach (var includeChildExpression in includeChildNodes) { var expression = includeChildExpression.Body; var propertiesInfo = new Stack <(string PropertyPath, Type PropertyType)>(); while (expression != null) { var expr = (expression as MemberExpression) ?? (expression as UnaryExpression)?.Operand as MemberExpression; if (expr == null) { if (expression is MethodCallExpression) { var meth = (MethodCallExpression)expression; expression = meth.Object ?? meth.Arguments?.FirstOrDefault(); continue; } break; } var memberExpression = (expression as MemberExpression) ?? (expression as UnaryExpression)?.Operand as MemberExpression; var propertyType = (memberExpression?.Member as PropertyInfo)?.PropertyType ?? typeof(object); propertiesInfo.Push((expr.Member.Name, propertyType)); //returns the last property name expression = expr.Expression; } int level = 1; var exprNode = rootNode; StringBuilder sb = includeParent ? new StringBuilder() : null; foreach (var propertyInfo in propertiesInfo) { string propertyPath = propertyInfo.PropertyPath; var existingNode = exprNode.Children.FirstOrDefault(c => c.Name == propertyPath); if (existingNode == null) { var isList = propertyInfo.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType); var newNode = new EntityNodeInfo() { Name = propertyPath, IsList = isList, Level = level }; if (includeParent) { if (sb.Length > 0) { sb.Append('.'); } sb.Append(propertyInfo.PropertyPath); newNode.PathName = sb.ToString(); } exprNode.Children.Add(newNode); exprNode = newNode; } else { exprNode = existingNode; } level++; } } return(rootNode); }