示例#1
0
        private void AddPropertiesToFetchTree <T>(
            ref int aliasCounter,
            ref int numberCollectionFetches,
            Stack <string> entityNames,
            FetchNode currentNode,
            FetchNode rootNode)
        {
            while (entityNames.Count > 0)
            {
                var propName = entityNames.Pop();

                // don't add duplicates
                if (!currentNode.Children.ContainsKey(propName))
                {
                    var column =
                        this.configuration.GetMap(
                            currentNode == rootNode
                                ? typeof(T)
                                : (currentNode.Column.Relationship == RelationshipType.OneToMany
                                       ? currentNode.Column.Type.GetGenericArguments().First()
                                       : currentNode.Column.Type)).Columns[propName];
                    if (column.IsIgnored)
                    {
                        //TODO we should probably warn at this point
                        continue;
                    }

                    if (column.Relationship == RelationshipType.OneToMany)
                    {
                        ++numberCollectionFetches;
                    }

                    // add to tree
                    currentNode = currentNode.AddChild(column, true);
                }
                else
                {
                    currentNode = currentNode.Children[propName];
                }
            }
        }
        protected override void VisitMember(Context context, MemberExpression node)
        {
            FetchNode fetchNode = null;

            this.VisitMember(node, x => fetchNode = x);
            if (!context.Parent.IsExpressionOf(ExpressionType.MemberAccess))
            {
                // we're at the end
                var map = ReferenceEquals(this.rootNode, fetchNode)
                              ? this.configuration.GetMap <TBase>()
                              : (fetchNode.Column.Relationship == RelationshipType.ManyToOne
                                     ? fetchNode.Column.ParentMap
                                     : (fetchNode.Column.Relationship == RelationshipType.OneToOne
                                            ? fetchNode.Column.OppositeColumn.Map
                                            : throw new NotSupportedException("Include/Exclude clauses can only use Many to One and One to One relationships")));

                if (map.Columns.TryGetValue(node.Member.Name, out var column))
                {
                    if (column.Relationship == RelationshipType.None)
                    {
                        // add to the included columns for this node
                        if (fetchNode.IncludedColumns == null)
                        {
                            fetchNode.IncludedColumns = new List <IColumn>();
                        }

                        fetchNode.IncludedColumns.Add(column);
                    }
                    else if (column.Relationship == RelationshipType.ManyToOne || column.Relationship == RelationshipType.OneToOne)
                    {
                        // add a new fetch node for this column
                        if (!fetchNode.Children.ContainsKey(column.Name))
                        {
                            fetchNode.AddChild(column, true);
                        }
                    }
                    else
                    {
                        throw new NotSupportedException($"Unable to project OneToMany relationships - {column.Name}");
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Unable to find column {node.Member.Name} in projection");
                }
            }
            else
            {
                // we're not at the end of the member access
                var declaringType = node.Member.DeclaringType;
                if (!this.configuration.HasMap(declaringType))
                {
                    throw new InvalidOperationException($"Type not mapped: {declaringType.FullName}");
                }

                var map = this.configuration.GetMap(declaringType);
                if (!fetchNode.Children.ContainsKey(node.Member.Name))
                {
                    context.State(fetchNode.AddChild(map.Columns[node.Member.Name], true));
                }
                else
                {
                    context.State(fetchNode.Children[node.Member.Name]);
                }
            }
        }