public static void Replace(Expression oldNode, Expression newNode) { if (oldNode == null) { throw new ArgumentNullException("oldNode"); } if (newNode == null) { throw new ArgumentNullException("newNode"); } Expression parent = oldNode.Owner; switch (parent.NodeType) { case NodeType.Axis: { Axis axis = (Axis)parent; if (axis.Source == oldNode) { axis.Source = newNode; } else if (axis.Constraint == oldNode) { axis.Constraint = newNode; } break; } case NodeType.Binary: { Binary binary = (Binary)parent; if (binary.Left == oldNode) { binary.Left = newNode; } else if (binary.Right == oldNode) { binary.Right = newNode; } break; } case NodeType.Filter: { Filter filter = (Filter)parent; if (filter.Source == oldNode) { filter.Source = newNode; } else if (filter.Constraint == oldNode) { filter.Constraint = newNode; } break; } case NodeType.Function: { Function function = (Function)parent; for (int i = 0; i < function.Params.Length; i++) { if (function.Params[i] == oldNode) { function.Params[i] = newNode; } } break; } case NodeType.Property: { Property property = (Property)parent; if (property.Source == oldNode) { property.Source = newNode; } break; } case NodeType.TypeFilter: { TypeFilter filter = (TypeFilter)parent; if (filter.Source == oldNode) { filter.Source = newNode; } break; } case NodeType.Unary: { Unary unary = (Unary)parent; if (unary.Operand == oldNode) { unary.Operand = newNode; } break; } default: { throw new NotSupportedException("Node type '" + oldNode.Owner.NodeType + "' was not expected."); } } // remove old node's parent association oldNode.Parent = null; }
public static void EnumNodes(Expression root, EnumNodesCallBack callback, EnumNodesCallBack postCallback, params object[] args) { switch (root.NodeType) { case NodeType.Literal: case NodeType.Parameter: case NodeType.Context: { if (callback != null) { callback(root, args); } if (postCallback != null) { postCallback(root, args); } return; } case NodeType.Binary: { if (callback == null || callback(root, args)) { Binary node = (Binary)root; Expression.EnumNodes(node.Left, callback, postCallback, args); Expression.EnumNodes(node.Right, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.Unary: { if (callback == null || callback(root, args)) { Unary node = (Unary)root; Expression.EnumNodes(node.Operand, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.Axis: case NodeType.Filter: { if (callback == null || callback(root, args)) { Filter node = (Filter)root; Expression.EnumNodes(node.Source, callback, postCallback, args); Expression.EnumNodes(node.Constraint, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.Property: { if (callback == null || callback(root, args)) { Property node = (Property)root; Expression.EnumNodes(node.Source, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.Parent: { if (callback == null || callback(root, args)) { Parent node = (Parent)root; Expression.EnumNodes(node.Source, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.Function: { if (callback == null || callback(root, args)) { Function node = (Function)root; for (int i = 0; i < node.Params.Length; i++) { Expression.EnumNodes(node.Params[i], callback, postCallback, args); } if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.TypeFilter: { if (callback == null || callback(root, args)) { TypeFilter node = (TypeFilter)root; Expression.EnumNodes(node.Source, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } case NodeType.Empty: { return; } case NodeType.OrderBy: { if (callback == null || callback(root, args)) { OrderBy node = (OrderBy)root; Expression.EnumNodes(node.Source, callback, postCallback, args); if (postCallback != null) { postCallback(root, args); } } return; } default: { throw new NotSupportedException("Expression type '" + root.GetType() + "' is not currently supported."); } } }
private void SetPropertyInfo(Property prop) { Expression link = (prop.Source as Context).Link; if (link.NodeType == NodeType.Filter) { Filter filter = (Filter)link; link = (filter.Source as Property); } if (link == null) { throw new Exception("Property '" + prop.Name + "' does not have a SourceLink node."); } Type ownerClass = null; if (link.NodeType == NodeType.TypeFilter) { TypeFilter node = (TypeFilter)link; ownerClass = node.Type; } else if (link.NodeType == NodeType.Property) { Property p = (Property)link; if (p.PropertyType == null) { SetPropertyInfo(p); } ownerClass = p.PropertyType; } else { throw new NotImplementedException("Property link of type '" + link.NodeType + "' was not expected."); } prop.OwnerClass = ownerClass; EntityMap entity = _maps[ownerClass]; if (entity == null) { throw new Exception("Type " + ownerClass + " does not have an entity mapping defined to the database."); } if (prop.IsRelational) { RelationMap rel = entity.Relation(prop.Name); if (rel == null) { throw new Exception("Type '" + ownerClass + "' does not have a relationship named '" + prop.Name + "' in the entity map."); } prop.PropertyType = EntityMap.GetType(rel.Type); prop.RelationMap = rel; } else { FieldMap field = entity.GetFieldMap(prop.Name); if (field == null) // NOTE: we never get a chance to throw our exception, get field map beats us to it { throw new Exception("Type '" + ownerClass + "' does not have a property named '" + prop.Name + "' in the entity map."); } prop.PropertyType = field.MemberType; prop.RelationMap = null; } }