public static EntityExpression Create(EntityFieldExpression entityFieldExpression, int offset)
        {
            var typeInfo      = entityFieldExpression.PersistentType;
            var fields        = new List <PersistentFieldExpression>();
            var keyExpression = KeyExpression.Create(typeInfo, offset);

            fields.Add(keyExpression);
            foreach (var nestedField in typeInfo.Fields)
            {
                fields.Add(BuildNestedFieldExpression(nestedField, offset));
            }
            var result = new EntityExpression(typeInfo, keyExpression, null, entityFieldExpression.DefaultIfEmpty)
            {
                Fields = fields
            };

            if (entityFieldExpression.OuterParameter == null)
            {
                return(result);
            }
            return((EntityExpression)result.BindParameter(entityFieldExpression.OuterParameter, new Dictionary <Expression, Expression>()));
        }
        public Expression Remap(int offset, Dictionary <Expression, Expression> processedExpressions)
        {
            if (!CanRemap)
            {
                return(this);
            }
            Expression value;

            if (processedExpressions.TryGetValue(this, out value))
            {
                return(value);
            }

            var keyExpression = (KeyExpression)Key.Remap(offset, processedExpressions);
            var result        = new EntityExpression(PersistentType, keyExpression, OuterParameter, DefaultIfEmpty);

            processedExpressions.Add(this, result);
            result.IsNullable = IsNullable;
            result.Fields     = Fields
                                .Select(f => f.Remap(offset, processedExpressions))
                                .Cast <PersistentFieldExpression>()
                                .ToList();
            return(result);
        }
        public ItemProjectorExpression EnsureEntityIsJoined()
        {
            var dataSource = DataSource;
            var newItem    = new ExtendedExpressionReplacer(e => {
                if (e is EntityExpression)
                {
                    var entityExpression = (EntityExpression)e;
                    var typeInfo         = entityExpression.PersistentType;
                    if (typeInfo.Fields.All(fieldInfo => entityExpression.Fields.Any(entityField => entityField.Name == fieldInfo.Name)))
                    {
                        return(entityExpression);
                    }
                    var joinedIndex = typeInfo.Indexes.PrimaryIndex;
                    var joinedRs    = joinedIndex.GetQuery().Alias(Context.GetNextAlias());
                    var keySegment  = entityExpression.Key.Mapping;
                    var keyPairs    = keySegment.GetItems()
                                      .Select((leftIndex, rightIndex) => new Pair <int>(leftIndex, rightIndex))
                                      .ToArray();
                    var offset           = dataSource.Header.Length;
                    var dataSourceAsJoin = dataSource as JoinProvider;
                    dataSource           = entityExpression.IsNullable || (dataSourceAsJoin != null && dataSourceAsJoin.JoinType == JoinType.LeftOuter)
            ? dataSource.LeftJoin(joinedRs, keyPairs)
            : dataSource.Join(joinedRs, keyPairs);
                    EntityExpression.Fill(entityExpression, offset);
                    return(entityExpression);
                }
                if (e is EntityFieldExpression)
                {
                    var entityFieldExpression = (EntityFieldExpression)e;
                    if (entityFieldExpression.Entity != null)
                    {
                        return(entityFieldExpression.Entity);
                    }
                    var typeInfo    = entityFieldExpression.PersistentType;
                    var joinedIndex = typeInfo.Indexes.PrimaryIndex;
                    var joinedRs    = joinedIndex.GetQuery().Alias(Context.GetNextAlias());
                    var keySegment  = entityFieldExpression.Mapping;
                    var keyPairs    = keySegment.GetItems()
                                      .Select((leftIndex, rightIndex) => new Pair <int>(leftIndex, rightIndex))
                                      .ToArray();
                    var offset           = dataSource.Header.Length;
                    var dataSourceAsJoin = dataSource as JoinProvider;
                    dataSource           = entityFieldExpression.IsNullable || (dataSourceAsJoin != null && dataSourceAsJoin.JoinType == JoinType.LeftOuter)
            ? dataSource.LeftJoin(joinedRs, keyPairs)
            : dataSource.Join(joinedRs, keyPairs);
                    entityFieldExpression.RegisterEntityExpression(offset);
                    return(entityFieldExpression.Entity);
                }
                if (e is FieldExpression)
                {
                    var fe = (FieldExpression)e;
                    if (fe.ExtendedType == ExtendedExpressionType.Field)
                    {
                        return(fe.RemoveOwner());
                    }
                }
                return(null);
            })
                             .Replace(Item);

            return(new ItemProjectorExpression(newItem, dataSource, Context));
        }
예제 #4
0
 public void RegisterEntityExpression(int offset)
 {
     Entity            = EntityExpression.Create(this, offset);
     Entity.IsNullable = IsNullable;
 }
        public ItemProjectorExpression EnsureEntityIsJoined()
        {
            var dataSource = DataSource;
            var newItem    = new ExtendedExpressionReplacer(e => {
                if (e is EntityExpression entityExpression)
                {
                    var typeInfo = entityExpression.PersistentType;

                    // Converted from LINQ to get rid of 2 closure allocations
                    var all = true;
                    foreach (var fieldInfo in typeInfo.Fields)
                    {
                        var isUsedInEntityExpression = false;
                        foreach (var entityField in entityExpression.Fields)
                        {
                            if (string.Equals(entityField.Name, fieldInfo.Name, StringComparison.Ordinal))
                            {
                                isUsedInEntityExpression = true;
                                break;
                            }
                        }
                        if (!isUsedInEntityExpression)
                        {
                            all = false;
                            break;
                        }
                    }

                    if (all)
                    {
                        return(entityExpression);
                    }

                    var joinedIndex = typeInfo.Indexes.PrimaryIndex;
                    var joinedRs    = joinedIndex.GetQuery().Alias(Context.GetNextAlias());
                    var keySegment  = entityExpression.Key.Mapping;
                    var keyPairs    = new Pair <int> [keySegment.Length];
                    var rightIndex  = 0;
                    foreach (var leftIndex in keySegment.GetItems())
                    {
                        keyPairs[rightIndex] = new Pair <int>(leftIndex, rightIndex);
                        rightIndex++;
                    }
                    var offset = dataSource.Header.Length;
                    dataSource = entityExpression.IsNullable ||
                                 (dataSource is JoinProvider dataSourceAsJoin && dataSourceAsJoin.JoinType == JoinType.LeftOuter)
              ? dataSource.LeftJoin(joinedRs, keyPairs)
              : dataSource.Join(joinedRs, keyPairs);
                    EntityExpression.Fill(entityExpression, offset);
                    return(entityExpression);
                }

                if (e is EntityFieldExpression entityFieldExpression)
                {
                    if (entityFieldExpression.Entity != null)
                    {
                        return(entityFieldExpression.Entity);
                    }

                    var typeInfo    = entityFieldExpression.PersistentType;
                    var joinedIndex = typeInfo.Indexes.PrimaryIndex;
                    var joinedRs    = joinedIndex.GetQuery().Alias(Context.GetNextAlias());
                    var keySegment  = entityFieldExpression.Mapping;
                    var keyPairs    = new Pair <int> [keySegment.Length];
                    var rightIndex  = 0;
                    foreach (var leftIndex in keySegment.GetItems())
                    {
                        keyPairs[rightIndex] = new Pair <int>(leftIndex, rightIndex);
                        rightIndex++;
                    }
                    var offset = dataSource.Header.Length;
                    dataSource = entityFieldExpression.IsNullable ||
                                 (dataSource is JoinProvider dataSourceAsJoin && dataSourceAsJoin.JoinType == JoinType.LeftOuter)
              ? dataSource.LeftJoin(joinedRs, keyPairs)
              : dataSource.Join(joinedRs, keyPairs);
                    entityFieldExpression.RegisterEntityExpression(offset);
                    return(entityFieldExpression.Entity);
                }

                if (e is FieldExpression fe && fe.ExtendedType == ExtendedExpressionType.Field)
                {
                    return(fe.RemoveOwner());
                }

                return(null);
            })
                             .Replace(Item);

            return(new ItemProjectorExpression(newItem, dataSource, Context));
        }