Beispiel #1
0
#pragma warning restore CS0612 // Type or member is obsolete
#pragma warning restore EF1001 // Internal EF Core API usage.

        /// <summary>
        ///     Sets the LINQ query used as the default source for queries of this type.
        /// </summary>
        /// <param name="entityType">The entity type.</param>
        /// <param name="inMemoryQuery">The LINQ query used as the default source.</param>
        public static void SetInMemoryQuery(
            this IMutableEntityType entityType,
            LambdaExpression?inMemoryQuery)
        => entityType
#pragma warning disable EF1001 // Internal EF Core API usage.
#pragma warning disable CS0612 // Type or member is obsolete
        .SetOrRemoveAnnotation(CoreAnnotationNames.DefiningQuery, inMemoryQuery);
Beispiel #2
0
    public static Expression?BindMemberExpression(MemberExpression m, bool allowPolymorphics)
    {
        PropertyInfo?pi = m.Member as PropertyInfo;

        if (pi == null)
        {
            return(null);
        }

        if (pi.HasAttributeInherit <PolymorphicExpansionAttribute>() && !allowPolymorphics)
        {
            return(null);
        }

        LambdaExpression?lambda = GetFieldExpansion(m.Expression?.Type, pi);

        if (lambda == null)
        {
            return(null);
        }

        if (m.Expression == null)
        {
            return(lambda.Body);
        }
        else
        {
            return(Expression.Invoke(lambda, m.Expression));
        }
    }
        internal static bool Equals(LambdaExpression?x, LambdaExpression?y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

            if (x is null || y is null)
            {
                return(false);
            }

            var xMember = x.GetRootProperty();
            var yMember = y.GetRootProperty();

            while (xMember != null &&
                   yMember != null)
            {
                if (!MemberExpressionComparer.Equals(xMember, yMember))
                {
                    return(false);
                }

                xMember = xMember.GetPreviousProperty();
                yMember = yMember.GetPreviousProperty();
            }

            return(xMember is null && yMember is null &&
                   x.GetSourceType() == y.GetSourceType());
        }
        protected EntityShaperExpression(
            [NotNull] IEntityType entityType,
            [NotNull] Expression valueBufferExpression,
            bool nullable,
            [CanBeNull] LambdaExpression?materializationCondition)
        {
            Check.NotNull(entityType, nameof(entityType));
            Check.NotNull(valueBufferExpression, nameof(valueBufferExpression));

            if (materializationCondition == null)
            {
                materializationCondition = GenerateMaterializationCondition(entityType, nullable);
            }
            else if (materializationCondition.Parameters.Count != 1 ||
                     materializationCondition.Parameters[0].Type != typeof(ValueBuffer) ||
                     materializationCondition.ReturnType != typeof(IEntityType))
            {
                throw new InvalidOperationException(CoreStrings.QueryEntityMaterializationConditionWrongShape(entityType.DisplayName()));
            }

            EntityType               = entityType;
            ValueBufferExpression    = valueBufferExpression;
            IsNullable               = nullable;
            MaterializationCondition = materializationCondition;
        }
Beispiel #5
0
 public BinaryExpression(BinaryOperator binaryOperator, Expression leftOperand, Expression rightOperand, bool liftToNull, MethodInfo?method, LambdaExpression?conversion = null)
     : this(binaryOperator, leftOperand, rightOperand)
 {
     IsLiftedToNull = liftToNull;
     Method         = method;
     Conversion     = conversion;
 }
Beispiel #6
0
    public static Expression?BindMethodExpression(MethodCallExpression m, bool allowPolymorphics)
    {
        if (m.Method.DeclaringType == typeof(ExpressionExtensions) && m.Method.Name == "Evaluate")
        {
            LambdaExpression lambda = (LambdaExpression)ExpressionEvaluator.Eval(m.Arguments[0]) !;

            return(Expression.Invoke(lambda, m.Arguments.Skip(1).ToArray()));
        }

        if (m.Method.HasAttributeInherit <PolymorphicExpansionAttribute>() && !allowPolymorphics)
        {
            return(null);
        }

        MethodExpanderAttribute?attribute = m.Method.GetCustomAttribute <MethodExpanderAttribute>();

        if (attribute != null)
        {
            if (attribute.ExpanderType.IsGenericTypeDefinition)
            {
                if (!typeof(GenericMethodExpander).IsAssignableFrom(attribute.ExpanderType))
                {
                    throw new InvalidOperationException("Expansion failed, '{0}' does not implement IMethodExpander or GenericMethodExpander".FormatWith(attribute.ExpanderType.TypeName()));
                }

                Expression[] args = m.Object == null?m.Arguments.ToArray() : m.Arguments.PreAnd(m.Object).ToArray();

                var type = attribute.ExpanderType.MakeGenericType(m.Method.GetGenericArguments());
                GenericMethodExpander expander = (GenericMethodExpander)Activator.CreateInstance(type) !;
                return(Expression.Invoke(expander.GenericLambdaExpression, args));
            }
            else
            {
                if (!typeof(IMethodExpander).IsAssignableFrom(attribute.ExpanderType))
                {
                    throw new InvalidOperationException("Expansion failed, '{0}' does not implement IMethodExpander or GenericMethodExpander".FormatWith(attribute.ExpanderType.TypeName()));
                }

                IMethodExpander expander = (IMethodExpander)Activator.CreateInstance(attribute.ExpanderType) !;

                Expression exp = expander.Expand(
                    m.Object,
                    m.Arguments.ToArray(),
                    m.Method);

                return(exp);
            }
        }

        LambdaExpression?lambdaExpression = GetFieldExpansion(m.Object?.Type, m.Method);

        if (lambdaExpression != null)
        {
            Expression[] args = m.Object == null?m.Arguments.ToArray() : m.Arguments.PreAnd(m.Object).ToArray();

            return(Expression.Invoke(lambdaExpression, args));
        }

        return(null);
    }
Beispiel #7
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            var obj = base.Visit(node.Object);

            var args = base.Visit(node.Arguments);

            LambdaExpression?lambda = ExpressionCleaner.GetFieldExpansion(obj?.Type, node.Method);

            if (lambda != null)
            {
                var replace = ExpressionReplacer.Replace(Expression.Invoke(lambda, obj == null ? args : args.PreAnd(obj)));

                return(this.Visit(replace));
            }

            if (node.Method.Name == "ToString" && node.Arguments.IsEmpty() && obj is CachedEntityExpression ce)
            {
                var table = (Table)ce.Constructor.table;

                if (table.ToStrColumn == null)
                {
                    throw new InvalidOperationException("Impossible to get ToStrColumn from " + ce.ToString());
                }

                return(BindMember(ce, (FieldValue)table.ToStrColumn, null));
            }

            return(node.Update(obj, args));
        }
Beispiel #8
0
        public OeEntryFactory(
            IEdmEntitySetBase entitySet,
            OePropertyAccessor[] accessors,
            OePropertyAccessor[]?skipTokenAccessors,
            IReadOnlyList <OeNavigationEntryFactory>?navigationLinks,
            LambdaExpression?linkAccessor)
            : this(entitySet, accessors, skipTokenAccessors)
        {
            NavigationLinks = navigationLinks ?? Array.Empty <OeNavigationEntryFactory>();

            if (linkAccessor != null)
            {
                IsTuple      = GetIsTuple(linkAccessor);
                LinkAccessor = (Func <Object, Object>)linkAccessor.Compile();
            }
            if (accessors.Length > 0)
            {
                if (IsExpandCount(accessors))
                {
                    _equalityComparer = Infrastructure.OeEntryEqualityComparer.ExpandCountEqualityComparer;
                }
                else
                {
                    _equalityComparer = new Infrastructure.OeEntryEqualityComparer(GetKeyExpressions(entitySet, accessors));
                }
            }
        }
        public static void SetInMemoryQuery(
            [NotNull] this IMutableEntityType entityType,
            [CanBeNull] LambdaExpression?inMemoryQuery)
        => Check.NotNull(entityType, nameof(entityType))
#pragma warning disable EF1001 // Internal EF Core API usage.
#pragma warning disable CS0612 // Type or member is obsolete
        .SetOrRemoveAnnotation(CoreAnnotationNames.DefiningQuery, inMemoryQuery);
 public static void SetDefiningQuery(
     [NotNull] this IConventionEntityType entityType,
     [CanBeNull] LambdaExpression?definingQuery,
     bool fromDataAnnotation = false)
 => ((EntityType)entityType).SetDefiningQuery(
     definingQuery,
     fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
Beispiel #11
0
        /// <summary>
        ///     Returns a value indicating whether the given in-memory query can be set from the current configuration source.
        /// </summary>
        /// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
        /// <param name="query"> The query that will provide the underlying data for the keyless entity type. </param>
        /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
        /// <returns> <see langword="true" /> if the given in-memory query can be set. </returns>
        public static bool CanSetInMemoryQuery(
            this IConventionEntityTypeBuilder entityTypeBuilder,
            LambdaExpression?query,
            bool fromDataAnnotation = false)
#pragma warning disable EF1001 // Internal EF Core API usage.
#pragma warning disable CS0612 // Type or member is obsolete
        => entityTypeBuilder.CanSetAnnotation(CoreAnnotationNames.DefiningQuery, query, fromDataAnnotation);
Beispiel #12
0
        protected override Expression VisitConstant(ConstantExpression c)
        {
            if (disableQueryFilter)
            {
                return(base.VisitConstant(c));
            }

            if (typeof(IQueryable).IsAssignableFrom(c.Type))
            {
                IQueryable query = (IQueryable)c.Value;

                if (query.IsBase())
                {
                    Type queryType = c.Type.GetGenericArguments().SingleEx();

                    if (filter)
                    {
                        if (typeof(Entity).IsAssignableFrom(queryType))
                        {
                            LambdaExpression?rawFilter = giFilter.GetInvoker(queryType)(Schema.Current);
                            if (rawFilter != null)
                            {
                                Expression clean       = ExpressionCleaner.Clean(rawFilter) !;
                                var        cleanFilter = (LambdaExpression)OverloadingSimplifier.Simplify(clean) !;

                                return(Expression.Call(miWhere.MakeGenericMethod(queryType), query.Expression, cleanFilter));
                            }
                        }
                        else if (queryType.IsInstantiationOf(typeof(MListElement <,>)))
                        {
                            Type entityType = queryType.GetGenericArguments()[0];

                            LambdaExpression?rawFilter = giFilter.GetInvoker(entityType)(Schema.Current);
                            if (rawFilter != null)
                            {
                                var param  = Expression.Parameter(queryType, "mle");
                                var lambda = Expression.Lambda(Expression.Invoke(rawFilter, Expression.Property(param, "Parent")), param);

                                Expression clean       = ExpressionCleaner.Clean(lambda) !;
                                var        cleanFilter = (LambdaExpression)OverloadingSimplifier.Simplify(clean) !;

                                return(Expression.Call(miWhere.MakeGenericMethod(queryType), query.Expression, cleanFilter));
                            }
                        }
                    }

                    return(c);
                }
                else
                {
                    /// <summary>
                    /// Replaces every expression like ConstantExpression{ Type = IQueryable, Value = complexExpr } by complexExpr
                    /// </summary>
                    return(DbQueryProvider.Clean(query.Expression, filter, null) !);
                }
            }

            return(base.VisitConstant(c));
        }
 /// <summary>
 /// Initializes a new instance with the specified parameters.
 /// </summary>
 public ArgumentInformation(ParameterInfo parameterInfo, Type?sourceType, FieldType?fieldType, TypeInformation typeInformation, LambdaExpression?expression)
 {
     ParameterInfo   = parameterInfo ?? throw new ArgumentNullException(nameof(parameterInfo));
     FieldType       = fieldType;  // ?? throw new ArgumentNullException(nameof(fieldType));
     SourceType      = sourceType; // ?? throw new ArgumentNullException(nameof(sourceType));
     TypeInformation = typeInformation ?? throw new ArgumentNullException(nameof(typeInformation));
     Expression      = expression;
 }
 public static LambdaExpression?SetQueryFilter(
     [NotNull] this IConventionEntityType entityType,
     [CanBeNull] LambdaExpression?queryFilter,
     bool fromDataAnnotation = false)
 => Check.NotNull(entityType, nameof(entityType)).AsEntityType()
 .SetQueryFilter(
     queryFilter,
     fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
Beispiel #15
0
 /// <summary>
 ///     Creates a new instance of the <see cref="RelationalEntityShaperExpression" /> class.
 /// </summary>
 /// <param name="entityType">The entity type to shape.</param>
 /// <param name="valueBufferExpression">An expression of ValueBuffer to get values for properties of the entity.</param>
 /// <param name="nullable">Whether this entity instance can be null.</param>
 /// <param name="materializationCondition">
 ///     An expression of <see cref="Func{T,TResult}" /> to determine which entity type to
 ///     materialize.
 /// </param>
 protected RelationalEntityShaperExpression(
     IEntityType entityType,
     Expression valueBufferExpression,
     bool nullable,
     LambdaExpression?materializationCondition)
     : base(entityType, valueBufferExpression, nullable, materializationCondition)
 {
 }
        protected QuerySplitBuilder(TBuilder?parent, LambdaExpression?idExpression, LambdaExpression?includeExpression, string?idPropertyName = null)
        {
            Parent             = parent;
            _idExpression      = idExpression;
            _includeExpression = includeExpression;
            _idPropertyName    = idPropertyName;

            Children = new List <TBuilder>();
        }
Beispiel #17
0
 internal MultipleQuerySplitBuilder(
     MultipleQuerySplitBuilder <T, TId>?parent,
     Expression <Func <T, TId> >?idExpression = null,
     LambdaExpression?derivedIdExpression     = null,
     LambdaExpression?includeExpression       = null)
     : base(parent, idExpression ?? derivedIdExpression, includeExpression)
 {
     _idExpression = idExpression;
 }
Beispiel #18
0
 internal LambdaExpression?GetConstructUsing()
 {
     if (!_fetchConstructUsing)
     {
         _constructUsing      = Settings.ConstructUsingFactory?.Invoke(this);
         _fetchConstructUsing = true;
     }
     return(_constructUsing);
 }
Beispiel #19
0
        private static bool GetIsTuple(LambdaExpression?linkAccessor)
        {
            if (linkAccessor != null && ((MemberExpression)linkAccessor.Body).Expression is UnaryExpression convertExpression)
            {
                return(OeExpressionHelper.IsTupleType(convertExpression.Type));
            }

            return(false);
        }
    /// <summary>
    /// 用于:Sum
    /// </summary>
    /// <param name="source"></param>
    /// <param name="lambda"></param>
    /// <returns></returns>
    public static object ExecuteSum(this IQueryable source, LambdaExpression?lambda = null)
    {
        var method = nameof(Queryable.Sum);

        var expression = lambda is null
            ? Expression.Call(typeof(Queryable), method, null, source.Expression)
            : Expression.Call(typeof(Queryable), method, new[] { source.ElementType }, source.Expression, lambda);

        return(source.Provider.Execute(expression));
    }
Beispiel #21
0
        /// <summary>
        ///     Configures a query used to provide data for an entity type.
        /// </summary>
        /// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
        /// <param name="query"> The query that will provide the underlying data for the entity type. </param>
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
        public static EntityTypeBuilder ToInMemoryQuery(
            this EntityTypeBuilder entityTypeBuilder,
            LambdaExpression?query)
        {
            Check.NotNull(query, nameof(query));

            entityTypeBuilder.Metadata.SetInMemoryQuery(query);

            return(entityTypeBuilder);
        }
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Method.DeclaringType == typeof(string) && node.Method.Name == nameof(string.Format) ||
                node.Method.DeclaringType == typeof(StringExtensions) && node.Method.Name == nameof(StringExtensions.FormatWith))
            {
                var formatStr  = Visit(node.Arguments[0]);
                var remainging = node.Arguments.Skip(1).Select(a => Visit(ToString(a))).ToList();


                return(node.Update(null, new Sequence <Expression> {
                    formatStr, remainging
                }));
            }

            var obj  = base.Visit(node.Object);
            var args = base.Visit(node.Arguments);

            if (node.Method.Name == "ToString" && node.Arguments.IsEmpty() && obj is CachedEntityExpression ce && ce.Type.IsEntity())
            {
                var table = (Table)ce.Constructor.table;

                if (table.ToStrColumn != null)
                {
                    return(BindMember(ce, (FieldValue)table.ToStrColumn, null));
                }
                else if (this.root != ce)
                {
                    var cachedTableType = typeof(CachedTable <>).MakeGenericType(table.Type);

                    ConstantExpression tab = Expression.Constant(ce.Constructor.cachedTable, cachedTableType);

                    var mi = cachedTableType.GetMethod(nameof(CachedTable <Entity> .GetToString));

                    return(Expression.Call(tab, mi, ce.PrimaryKey.UnNullify()));
                }
            }

            LambdaExpression?lambda = ExpressionCleaner.GetFieldExpansion(obj?.Type, node.Method);

            if (lambda != null)
            {
                var replace = ExpressionReplacer.Replace(Expression.Invoke(lambda, obj == null ? args : args.PreAnd(obj)));

                return(this.Visit(replace));
            }

            if (node.Method.Name == nameof(Entity.Mixin) && obj is CachedEntityExpression cee)
            {
                var mixin = ((Table)cee.Constructor.table).GetField(node.Method);

                return(GetField(mixin, cee.Constructor, cee.PrimaryKey));
            }

            return(node.Update(obj, args));
        }
Beispiel #23
0
        public static Expression?Replace(LambdaExpression?expression, ParameterExpression parameter)
        {
            if (expression == null)
            {
                return(null);
            }

            var visitor = new Replacer(expression.Parameters[0], parameter);

            return(visitor.Visit(expression.Body));
        }
        public static LambdaExpression?SetInMemoryQuery(
            [NotNull] this IConventionEntityType entityType,
            [CanBeNull] LambdaExpression?inMemoryQuery,
            bool fromDataAnnotation = false)
        => (LambdaExpression?)Check.NotNull(entityType, nameof(entityType))
#pragma warning disable EF1001 // Internal EF Core API usage.
#pragma warning disable CS0612 // Type or member is obsolete
        .SetOrRemoveAnnotation(CoreAnnotationNames.DefiningQuery, inMemoryQuery, fromDataAnnotation)
#pragma warning restore CS0612 // Type or member is obsolete
#pragma warning restore EF1001 // Internal EF Core API usage.
        ?.Value;
Beispiel #25
0
 public LambdaInfo(
     LambdaExpression checkNullLambda,
     LambdaExpression?lambda,
     Delegate?         @delegate,
     bool isSchemaSpecific)
 {
     CheckNullLambda  = checkNullLambda;
     Lambda           = lambda ?? checkNullLambda;
     Delegate         = @delegate;
     IsSchemaSpecific = isSchemaSpecific;
 }
        protected SequenceContextBase(IBuildContext?parent, IBuildContext[] sequences, LambdaExpression?lambda)
        {
            Parent      = parent;
            Sequences   = sequences;
            Builder     = sequences[0].Builder;
            Lambda      = lambda;
            SelectQuery = sequences[0].SelectQuery;

            Sequence.Parent = this;

            Builder.Contexts.Add(this);
        }
    /// <summary>
    /// 用于:Max、Min
    /// </summary>
    /// <param name="source"></param>
    /// <param name="method"></param>
    /// <param name="lambda"></param>
    /// <returns></returns>
    public static object ExecuteMaxMin(this IQueryable source, MethodInfo method, LambdaExpression?lambda = null)
    {
        method = method.GetGenericArguments().Length == 2
            ? method.MakeGenericMethod(source.ElementType, lambda?.ReturnType)
            : method.MakeGenericMethod(source.ElementType);

        var expression = lambda is null
            ? Expression.Call(method, source.Expression)
            : Expression.Call(method, source.Expression, lambda);

        return(source.Provider.Execute(expression));
    }
        public static bool TryRewriteLamdaExpression(
            LambdaExpression lambdaExpression,
            Dictionary <ParameterExpression, GroupingDescriptor> lambdaParamsToRewrite,
            [NotNullWhen(true)] out LambdaExpression?translatedArg)
        {
            _instance ??= new GroupingExpressionRewriter();
            _instance._lambdaParamsToRewrite = lambdaParamsToRewrite;
            _instance._success = true;

            translatedArg = (LambdaExpression)_instance.Visit(lambdaExpression);
            _instance._rewrittenLamdaParameters.Clear();
            return(_instance._success);
        }
    /// <summary>
    /// 用于:First、FirstOrDefault、Last、LastOrDefault、Single、SingleOrDefault
    /// </summary>
    /// <param name="source"></param>
    /// <param name="method"></param>
    /// <param name="lambda"></param>
    /// <returns></returns>
    public static object Execute(this IQueryable source, MethodInfo method, LambdaExpression?lambda = null)
    {
        if (method.IsGenericMethod)
        {
            method = method.MakeGenericMethod(source.ElementType);
        }

        var expression = lambda is null
            ? Expression.Call(method, source.Expression)
            : Expression.Call(method, source.Expression, lambda);

        return(source.Provider.Execute(expression));
    }
        // Returns
        // (ParentType p) => dc.GetTable<ObjectType>().Where(...)
        // (ParentType p) => dc.GetTable<ObjectType>().Where(...).DefaultIfEmpty
        public static LambdaExpression CreateAssociationQueryLambda(ExpressionBuilder builder, AccessorMember onMember, AssociationDescriptor association,
                                                                    Type parentOriginalType,
                                                                    Type parentType,
                                                                    Type objectType, bool inline, bool enforceDefault,
                                                                    List <LoadWithInfo[]>?loadWith, out bool isLeft)
        {
            var dataContextConstant = Expression.Constant(builder.DataContext, builder.DataContext.GetType());

            // We are trying to keep fast cache hit behaviour, so cache check should be added only if needed
            //
            bool shouldAddCacheCheck = false;

            bool cacheCheckAdded = false;

            LambdaExpression?definedQueryMethod = null;

            if (association.HasQueryMethod())
            {
                // here we tell for Expression Comparer to compare optimized Association expressions
                //
                definedQueryMethod = (LambdaExpression)builder.AddQueryableMemberAccessors(onMember, builder.DataContext, (mi, dc) =>
                {
                    var queryLambda         = association.GetQueryMethod(parentType, objectType) ?? throw new InvalidOperationException();
                    var optimizationContext = new ExpressionTreeOptimizationContext(dc);
                    var optimizedExpr       = optimizationContext.ExposeExpression(queryLambda);
                    optimizedExpr           = optimizationContext.ExpandQueryableMethods(optimizedExpr);
                    return(optimizedExpr);
                });

                cacheCheckAdded = true;

                var parameterMatch = new Dictionary <ParameterExpression, Expression>();
                if (onMember.Arguments == null)
                {
                    if (definedQueryMethod.Parameters.Count > 1 && typeof(IDataContext).IsSameOrParentOf(definedQueryMethod.Parameters[1].Type))
                    {
                        parameterMatch.Add(definedQueryMethod.Parameters[1], dataContextConstant);
                    }
                }
                else
                {
                    var definedCount   = definedQueryMethod.Parameters.Count;
                    var argumentsCount = onMember.Arguments.Count;
                    var diff           = definedCount - argumentsCount;
                    for (int i = definedCount - 1; i >= diff; i--)
                    {
                        parameterMatch.Add(definedQueryMethod.Parameters[i], onMember.Arguments[i - diff]);
                    }
                }

                var body = definedQueryMethod.Body.Transform(parameterMatch, static (parameterMatch, e) =>