Esempio n. 1
0
        private String TitleFor(Expression <Func <T, TValue> > expression)
        {
            MemberExpression?body    = expression.Body as MemberExpression;
            DisplayAttribute?display = body?.Member.GetCustomAttribute <DisplayAttribute>();

            return(display?.GetShortName() ?? "");
        }
Esempio n. 2
0
        public static PropertyInfo GetPropertyInfo <TSource, TProperty>(
            this Expression <Func <TSource, TProperty> > propertyLambda)
        {
            // https://stackoverflow.com/a/672212/169336
            Type type = typeof(TSource);

            MemberExpression?member = propertyLambda.Body as MemberExpression;

            if (member is null)
            {
                throw new ArgumentException($"Expression '{propertyLambda}' refers to a method, not a property.");
            }

            PropertyInfo?propInfo = member.Member as PropertyInfo;

            if (propInfo is null)
            {
                throw new ArgumentException($"Expression '{propertyLambda}' refers to a field, not a property.");
            }

            if (propInfo.ReflectedType != null &&
                type != propInfo.ReflectedType &&
                !type.IsSubclassOf(propInfo.ReflectedType))
            {
                throw new ArgumentException($"Expression '{propertyLambda}' refers to a property that is not from type {type}.");
            }

            return(propInfo);
        }
    protected override Expression VisitMember(MemberExpression member)
    {
        MemberExpression?candidate = MakeCandidateMatch(member);

        CheckEqual(member.Member, candidate?.Member);
        return(base.VisitMember(member));
    }
    protected override string VisitMemberAccess(MemberExpression?m)
    {
        if (m is null)
        {
            return(string.Empty);
        }

        if (m.Expression != null && m.Expression.NodeType == ExpressionType.Parameter &&
            m.Expression.Type == typeof(TDto))
        {
            return(Visited ? string.Empty : GetFieldName(_pd, m.Member.Name, _alias));
        }

        if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
        {
            return(Visited ? string.Empty : GetFieldName(_pd, m.Member.Name, _alias));
        }

        UnaryExpression member = Expression.Convert(m, typeof(object));
        var             lambda = Expression.Lambda <Func <object> >(member);
        Func <object>   getter = lambda.Compile();
        var             o      = getter();

        SqlParameters.Add(o);

        return(Visited ? string.Empty : "@" + (SqlParameters.Count - 1));
    }
        private static string ParseMemberExpression(MemberExpression?exp, IDictionary <string, string>?columnMappings)
        {
            if (exp == null)
            {
                return(string.Empty);
            }
            if (exp.Member.DeclaringType == typeof(DateTime))
            {
                return(ParseDateTimeMemberAccess(exp, columnMappings));
            }
            if (exp.Member.DeclaringType == typeof(string))
            {
                return(ParseStringMemberAccess(exp, columnMappings));
            }
            var memberName = exp.Member.Name;

            if (columnMappings != null && columnMappings.Count > 0)
            {
                var mapping = columnMappings.FirstOrDefault(_ => _.Value == memberName);
                if (mapping.Key.IsNotNullOrWhiteSpace())
                {
                    return(mapping.Key);
                }
            }
            return(memberName);
        }
Esempio n. 6
0
        /// <summary>
        /// Generates the <see cref="Expression"/> for accessing a member by name.
        /// </summary>
        /// <param name="self">
        /// The <see cref="Expression"/> for accessing the <see cref="Exposed"/> instance.
        /// </param>
        /// <param name="memberName">
        /// The member name.
        /// </param>
        /// <returns>
        /// <see cref="MemberExpression"/> for accessing a member by name.
        /// </returns>
        /// <exception cref="MissingMemberException">
        /// </exception>
        private MemberExpression GetMemberExpression(Expression self, string memberName)
        {
            MemberExpression?memberExpression = null;
            var type  = ((Exposed)Value !).SubjectType;
            var @this = isStatic
                            ? null
                            : Expression.Convert(Expression.Field(Expression.Convert(self, typeof(Exposed)), "value"), type);
            var declaringType = type;

            do
            {
                var property = declaringType.GetProperty(memberName, GetBindingFlags());
                if (property != null)
                {
                    memberExpression = Expression.Property(@this, property);
                }
                else
                {
                    var field = declaringType.GetField(memberName, GetBindingFlags());
                    if (field != null)
                    {
                        memberExpression = Expression.Field(@this, field);
                    }
                }
            }while (memberExpression == null && (declaringType = declaringType.BaseType) != null);

            if (memberExpression == null)
            {
                throw new MissingMemberException(type.FullName, memberName);
            }

            return(memberExpression);
        }
Esempio n. 7
0
        private static MemberExpression GetMemberExpression(Expression body)
        {
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }

            MemberExpression?memberExpression = null;

            if (body.NodeType == ExpressionType.Convert)
            {
                var unaryExpression = (UnaryExpression)body;
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
            else if (body.NodeType == ExpressionType.MemberAccess)
            {
                memberExpression = body as MemberExpression;
            }

            if (memberExpression == null)
            {
                throw new ArgumentException("Expression is not a member access.");
            }

            return(memberExpression);
        }
Esempio n. 8
0
        protected override IQueryable <Subscription> GetSubscribers(BotContext context, string[] criterias)
        {
            if (criterias.Length > 0)
            {
                Expression?filter = null;
                ParameterExpression[]? parameter = null;
                MemberExpression?subscriptionBedingungen = null;
                foreach (string criteria in criterias)
                {
                    Expression <Func <Subscription, bool> > condition = subscription => subscription.Bedingungen.Any(a => a.Bedingung.Contains(criteria));
                    if (filter == null)
                    {
                        filter    = condition.Body;
                        parameter = condition.Parameters.ToArray();
                        subscriptionBedingungen = Expression.Property(parameter[0], nameof(Subscription.Bedingungen));
                        continue;
                    }

                    var methodCall = (MethodCallExpression)condition.Body;
                    methodCall = Expression.Call(methodCall.Method, subscriptionBedingungen, methodCall.Arguments[1]);

                    filter = Expression.OrElse(filter, methodCall);
                }

                Expression <Func <Subscription, bool> > finalFilter = Expression.Lambda <Func <Subscription, bool> >(filter, parameter);
                return(base.GetSubscribers(context, criterias).Where(finalFilter));
            }
            return(base.GetSubscribers(context, criterias));
        }
Esempio n. 9
0
        private MethodCallExpression ApplyAggregate(Expression source, AggregateTransformationNode transformation)
        {
            Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type);
            ParameterExpression sourceParameter = Expression.Parameter(sourceType);
            ParameterExpression lambdaParameter = sourceParameter;

            var  expressions = new List <Expression>();
            bool isGroupBy   = sourceType.GetGenericTypeDefinition() == typeof(IGrouping <,>);

            if (isGroupBy)
            {
                PropertyInfo     keyProperty = sourceType.GetProperty(nameof(IGrouping <Object, Object> .Key)) !;
                MemberExpression key         = Expression.Property(sourceParameter, keyProperty);
                expressions.Add(key);

                lambdaParameter = Expression.Parameter(sourceType.GetGenericArguments()[1]);
            }

            var visitor = CreateVisitor(lambdaParameter);

            foreach (AggregateExpressionBase aggExpressionBase in transformation.AggregateExpressions)
            {
                if (aggExpressionBase is AggregateExpression aggExpression)
                {
                    MethodCallExpression aggCallExpression;
                    if (aggExpression.Method == AggregationMethod.VirtualPropertyCount)
                    {
                        aggCallExpression = CountExpression(sourceParameter);
                    }
                    else
                    {
                        Expression expression = visitor.TranslateNode(aggExpression.Expression);
                        if (isGroupBy && expression is MemberExpression propertyExpression)
                        {
                            MemberExpression?keyPropertyExpression = FindInGroupByKey(source, expressions[0], propertyExpression);
                            if (keyPropertyExpression != null)
                            {
                                expression = keyPropertyExpression;
                            }
                        }
                        LambdaExpression aggLambda = Expression.Lambda(expression, lambdaParameter);
                        aggCallExpression = AggCallExpression(aggExpression.Method, sourceParameter, aggLambda);
                    }
                    expressions.Add(aggCallExpression);
                    _aggProperties.Add(CreateEdmProperty(aggCallExpression.Type, aggExpression.Alias, false));
                }
                else
                {
                    throw new NotSupportedException("Unknown aggregate expression type " + aggExpressionBase.GetType().Name);
                }
            }

            NewExpression    newExpression    = OeExpressionHelper.CreateTupleExpression(expressions);
            MethodInfo       selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceType, newExpression.Type);
            LambdaExpression lambda           = Expression.Lambda(newExpression, sourceParameter);

            return(Expression.Call(selectMethodInfo, source, lambda));
        }
Esempio n. 10
0
        public static string GetMemberName(Expression expression)
        {
            UnaryExpression? unaryExpression  = expression as UnaryExpression;
            MemberExpression?memberExpression = unaryExpression == null ? expression as MemberExpression : unaryExpression.Operand as MemberExpression;

            if (memberExpression == null)
            {
                throw new ArgumentException("Expression was not of the form 'x => x.Property or x => x.Field'.");
            }
            return(memberExpression.Member.Name);
        }
Esempio n. 11
0
        public static string getReturnName(LambdaExpression expression)
        {
            MemberExpression?body = expression.Body as MemberExpression;

            if (body == null)
            {
                UnaryExpression ubody = (UnaryExpression)expression.Body;

                body = ubody.Operand as MemberExpression ??
                       throw new ArgumentException("Expression body is null");
            }

            return(body.Member.Name);
        }
        /// <summary>Determines whether the specified <see cref="MemberExpression"/>s are equal.</summary>
        /// <param name="x">The first <see cref="MemberExpression"/> to compare.</param>
        /// <param name="y">The second <see cref="MemberExpression"/> to compare.</param>
        /// <returns>true if the specified <see cref="MemberExpression"/>s are equal; otherwise, false.</returns>
        bool IEqualityComparer <MemberExpression> .Equals([AllowNull] MemberExpression?x, [AllowNull] MemberExpression?y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

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

            return(EqualsMember(x, y, BeginScope()));
        }
Esempio n. 13
0
        internal static bool Equals(MemberExpression?x, MemberExpression?y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

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

            return(x.Member == y.Member &&
                   x.Expression.Type == y.Expression.Type);
        }
    public static string GetPropertyPath <TType, TProperty>(Expression <Func <TType, TProperty> > propertySelector)
    {
        var memberExpression = GetMemberExpressionFromPropertySelector(propertySelector);

        var tokens = new LinkedList <string>();
        MemberExpression?currentMemberExpression = memberExpression;

        while (currentMemberExpression != null)
        {
            tokens.AddFirst(currentMemberExpression.Member.Name);
            currentMemberExpression = currentMemberExpression !.Expression as MemberExpression;
        }

        return(string.Join(".", tokens));
    }
        private static MemberInfo GetMemberInfo(LambdaExpression lambda)
        {
            if (lambda is null)
            {
                throw new ArgumentException("Not a property expression");
            }

            MemberExpression?memberExpression = null;

            switch (lambda.Body.NodeType)
            {
            case ExpressionType.Convert when lambda.Body is UnaryExpression {
                    Operand: MemberExpression unaryMemberExpression
            } :
                memberExpression = unaryMemberExpression;
                break;
        static MemberExpression GetMemberExpression <TEntity, TProperty>(this Expression <Func <TEntity, TProperty> > expression)
        {
            MemberExpression?memberExpression = null;

            if (expression.Body.NodeType == ExpressionType.Convert)
            {
                var body = (UnaryExpression)expression.Body;
                memberExpression = body.Operand as MemberExpression;
            }
            else if (expression.Body.NodeType == ExpressionType.MemberAccess)
            {
                memberExpression = expression.Body as MemberExpression;
            }

            return(memberExpression ?? throw new ArgumentException("Not a member access", nameof(expression)));
        }
Esempio n. 17
0
        PropertyMappingBuilder <TEntity, TProperty> SetColumn(Action <ColumnAttribute> setColumn)
        {
            var getter     = _memberGetter;
            var memberName = null as string;
            var me         = _memberGetter.Body.Unwrap() as MemberExpression;

            if (me != null && me.Expression is MemberExpression)
            {
                for (MemberExpression?m = me; m != null; m = m.Expression as MemberExpression)
                {
                    memberName = m.Member.Name + (memberName != null ? "." + memberName : "");
                }

                _entity.SetAttribute(
                    () =>
                {
                    var a = new ColumnAttribute {
                        Configuration = _entity.Configuration, MemberName = memberName
                    };
                    setColumn(a);
                    return(a);
                },
                    setColumn,
                    a => a.Configuration,
                    attrs => attrs.FirstOrDefault(_ => memberName == null || memberName.Equals(_.MemberName)));

                return(this);
            }

            _entity.SetAttribute(
                getter,
                false,
                _ =>
            {
                var a = new ColumnAttribute {
                    Configuration = _entity.Configuration, MemberName = memberName
                };
                setColumn(a);
                return(a);
            },
                (_, a) => setColumn(a),
                a => a.Configuration,
                a => new ColumnAttribute(a),
                attrs => attrs.FirstOrDefault(_ => memberName == null || memberName.Equals(_.MemberName)));

            return(this);
        }
Esempio n. 18
0
    public static MemberExpression GetPropertyExpression(
        this ParameterExpression parameterExpression,
        string propertyName)
    {
        MemberExpression?propertyExp = null;

        //Step down the property hierarchy
        foreach (var member in propertyName.Split('.'))
        {
            propertyExp = Expression.PropertyOrField((Expression?)propertyExp ?? parameterExpression, member);
        }

        if (propertyExp == null)
        {
            throw new ArgumentException($"Unable to resolve {propertyName} property", nameof(propertyName));
        }

        return(propertyExp);
    }
Esempio n. 19
0
        internal static PropertyInfo GetProperty <T>(Expression <Func <T, object?> > propertyExpression)
        {
            Expression expression = propertyExpression.Body;

            // If the Property returns a ValueType then a Convert is required => Remove it
            if (expression.NodeType == ExpressionType.Convert || expression.NodeType == ExpressionType.ConvertChecked)
            {
                expression = ((UnaryExpression)expression).Operand;
            }

            // If this isn't a member access expression then the expression isn't valid
            MemberExpression?memberExpression = expression as MemberExpression;

            if (memberExpression == null)
            {
                ThrowExpressionArgumentException();
            }

            expression = memberExpression !.Expression;

            // If the Property returns a ValueType then a Convert is required => Remove it
            if (expression.NodeType == ExpressionType.Convert || expression.NodeType == ExpressionType.ConvertChecked)
            {
                expression = ((UnaryExpression)expression).Operand;
            }

            // Check if the expression is the parameter itself
            if (expression.NodeType != ExpressionType.Parameter)
            {
                ThrowExpressionArgumentException();
            }

            // Finally retrieve the PropertyInfo
            PropertyInfo?propertyInfo = memberExpression.Member as PropertyInfo;

            if (propertyInfo == null)
            {
                ThrowExpressionArgumentException();
            }

            return(propertyInfo);
        }
        public static PropertyInfo GetAccessedMemberInfo <T>(this Expression <T> expression)
        {
            MemberExpression?memberExpression = null;

            if (expression.Body.NodeType == ExpressionType.Convert)
            {
                memberExpression = ((UnaryExpression)expression.Body).Operand as MemberExpression;
            }
            else if (expression.Body.NodeType == ExpressionType.MemberAccess)
            {
                memberExpression = expression.Body as MemberExpression;
            }

            if (memberExpression == null)
            {
                throw new ArgumentException("Not a member access", "expression");
            }

            return(memberExpression.Member as PropertyInfo ?? throw new Exception());
        }
        public static MemberExpression ReplaceParameter(MemberExpression propertyExpression, Expression newParameter)
        {
            var properties = new Stack <PropertyInfo>();
            MemberExpression?memberExpression = propertyExpression;

            do
            {
                properties.Push((PropertyInfo)memberExpression.Member);
                memberExpression = memberExpression.Expression as MemberExpression;
            }while (memberExpression != null);

            Expression expression = Expression.Convert(newParameter, properties.Peek().DeclaringType);

            while (properties.Count > 0)
            {
                expression = Expression.Property(expression, properties.Pop());
            }

            return((MemberExpression)expression);
        }
Esempio n. 22
0
        public static PropertyInfo GetPropertyInfo <TSource, TProperty>(TSource source, Expression <Func <TSource, TProperty> > propertyLambda)
        {
            Type type = typeof(TSource);

            MemberExpression?member = propertyLambda.Body as MemberExpression;

            if (member == null)
            {
                throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda));
            }

            PropertyInfo?propInfo = member.Member as PropertyInfo;

            if (propInfo == null)
            {
                throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", propertyLambda));
            }

            return(propInfo);
        }
Esempio n. 23
0
        /// <summary>
        /// extracts the constant value from a binary equals expression
        /// - either the left or right side of the expression
        /// </summary>
        /// <param name="be">binary expression</param>
        /// <param name="memberDeclaringType">type of object</param>
        /// <param name="memberName">member to get value for</param>
        /// <returns>string representation of value</returns>
        internal static string GetValueFromEqualsExpression(BinaryExpression be, Type memberDeclaringType, string memberName)
        {
            if (be.NodeType != ExpressionType.Equal &&
                be.NodeType != ExpressionType.NotEqual &&
                be.NodeType != ExpressionType.GreaterThan &&
                be.NodeType != ExpressionType.GreaterThanOrEqual &&
                be.NodeType != ExpressionType.LessThan &&
                be.NodeType != ExpressionType.LessThanOrEqual)
            {
                throw new Exception("There is a bug in this program.");
            }

            if (be.Left.NodeType == ExpressionType.MemberAccess ||
                be.Left.NodeType == ExpressionType.Convert ||
                be.Left.NodeType == ExpressionType.ConvertChecked)
            {
                // adjust for enums & VB ConvertChecked
                MemberExpression?me =
                    be.Left.NodeType == ExpressionType.Convert ||
                    be.Left.NodeType == ExpressionType.ConvertChecked ?
                    (be.Left as UnaryExpression)?.Operand as MemberExpression :
                    be.Left as MemberExpression;

                if (me?.Member.DeclaringType == memberDeclaringType && me.Member.Name == memberName)
                {
                    return(GetValueFromExpression(be.Right));
                }
            }
            else if (be.Right.NodeType == ExpressionType.MemberAccess)
            {
                MemberExpression me = (MemberExpression)be.Right;

                if (me.Member.DeclaringType == memberDeclaringType && me.Member.Name == memberName)
                {
                    return(GetValueFromExpression(be.Left));
                }
            }

            // We should have returned by now.
            throw new Exception("There is a bug in this program.");
        }
Esempio n. 24
0
        public MemberExpression GetJoinPropertyExpression(Expression source, Expression parameter, SingleValuePropertyAccessNode propertyNode)
        {
            IReadOnlyList <IEdmNavigationProperty> joinPath = GetJoinPath(propertyNode);
            MemberExpression?joinPropertyExpression         = GetJoinPropertyExpression(source, parameter, joinPath, propertyNode.Property);

            if (joinPropertyExpression != null)
            {
                return(joinPropertyExpression);
            }

            var propertyExpression = (MemberExpression)Visitor.TranslateNode(propertyNode);

            if (Visitor.Parameter == parameter)
            {
                return(propertyExpression);
            }

            var replaceParameterVisitor = new ReplaceParameterVisitor(Visitor.Parameter, parameter);

            return((MemberExpression)replaceParameterVisitor.Visit(propertyExpression));
        }
        public static PropertyInfo GetPropertyInfo <T, TProperty>(this Expression <Func <T, TProperty> > expression)
        {
            // Validate parameters.
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            // The member expression.
            MemberExpression?member = expression.Body as MemberExpression;

            // Used to generate the exception, if necessary.
            ArgumentException CreateExpressionNotPropertyException() =>
            new ArgumentException($"The expression parameter ({ nameof(expression) }) is not a property expression.");

            // If it's a convert, then get the expression in the convert.
            if (member == null && expression.Body.NodeType == ExpressionType.Convert)
            {
                // Get the convert.
                member = (expression.Body as UnaryExpression)?.Operand as MemberExpression;
            }

            // If not a member expression, throw an exception.
            if (member == null)
            {
                throw CreateExpressionNotPropertyException();
            }

            // Get the property info.
            // If it is null, throw an exception.
            if (!(member.Member is PropertyInfo propertyInfo))
            {
                throw CreateExpressionNotPropertyException();
            }

            // Return the property info.
            return(propertyInfo);
        }
        /// <summary>
        /// Extracts the property from a linq expression that accesses a property.
        /// </summary>
        /// <param name="propertyExpression">The expression to extract the property from.</param>
        /// <returns>The property that was extracted from the given expression.</returns>
        /// <exception cref="ArgumentException"><paramref name="propertyExpression" /> is null.</exception>
        /// <exception cref="ArgumentException"><paramref name="propertyExpression" /> is not a access call to a property.</exception>
        /// <exception cref="ArgumentException"><paramref name="propertyExpression" /> is accessing a property that does not have a public setter.</exception>
        /// <example>
        /// <code>
        /// class Item
        /// {
        ///     public Int32 PropertyA { get; set; }
        /// }
        ///
        /// Expression{Func{Item, Object}} expression = ((item) => item.PropertyA)
        /// ExpressionHelper.GetPropertyFromPropertyExpression(expression);  // returns same as typeof(Item).GetProperty("PropertyA") would.
        /// </code>
        /// </example>
        public static PropertyInfo GetPropertyFromPropertyExpression(LambdaExpression propertyExpression)
        {
            if (propertyExpression == null)
            {
                throw new ArgumentNullException(nameof(propertyExpression));
            }

            MemberExpression?memberExpression = null;

            if (propertyExpression.Body is MemberExpression expressionBody)
            {
                memberExpression = expressionBody;
            }

            if (
                propertyExpression.Body is UnaryExpression unaryExpression &&
                unaryExpression.NodeType == ExpressionType.Convert &&
                unaryExpression.Operand is MemberExpression operand
                )
            {
                memberExpression = operand;
            }

            PropertyInfo?propertyInfo = null;

            if (memberExpression != null)
            {
                propertyInfo = memberExpression.Member as PropertyInfo;
            }

            if (propertyInfo == null || !propertyInfo.HasPublicSetter())
            {
                throw new ArgumentException("The given property expression is invalid. It must be an expression that returns the value of a property and the property must have a public setter.", nameof(propertyExpression));
            }

            return(propertyInfo);
        }
Esempio n. 27
0
        private static bool TryGetMessageMemberExpression<TMessage>(Expression? expression, [NotNullWhen(true)] out MemberExpression? memberExpression)
        {
            memberExpression = expression as MemberExpression;
            if (memberExpression != null)
                return IsMessageMemberExpression<TMessage>(memberExpression);

            if (!(expression is UnaryExpression unaryExpression))
                return false;

            memberExpression = unaryExpression.Operand as MemberExpression;
            if (memberExpression == null)
                return false;

            return IsMessageMemberExpression<TMessage>(memberExpression);
        }
Esempio n. 28
0
 bool IEqualityComparer <MemberExpression> .Equals(MemberExpression?x, MemberExpression?y) => Equals(x, y);
 protected abstract string VisitMemberAccess(MemberExpression?m);
    protected override string VisitMemberAccess(MemberExpression?m)
    {
        if (m is null)
        {
            return(string.Empty);
        }

        if (m.Expression != null &&
            m.Expression.NodeType == ExpressionType.Parameter &&
            m.Expression.Type == typeof(T))
        {
            // don't execute if compiled
            if (Visited == false)
            {
                var field = _mapper?.Map(m.Member.Name);
                if (field.IsNullOrWhiteSpace())
                {
                    throw new InvalidOperationException(
                              $"The mapper returned an empty field for the member name: {m.Member.Name} for type: {m.Expression.Type}.");
                }

                return(field !);
            }

            // already compiled, return
            return(string.Empty);
        }

        if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
        {
            // don't execute if compiled
            if (Visited == false)
            {
                var field = _mapper?.Map(m.Member.Name);
                if (field.IsNullOrWhiteSpace())
                {
                    throw new InvalidOperationException(
                              $"The mapper returned an empty field for the member name: {m.Member.Name} for type: {m.Expression.Type}.");
                }

                return(field !);
            }

            // already compiled, return
            return(string.Empty);
        }

        if (m.Expression != null &&
            m.Expression.Type != typeof(T) &&
            EndsWithConstant(m) == false &&
            _mappers is not null &&
            _mappers.TryGetMapper(m.Expression.Type, out BaseMapper? subMapper))
        {
            // if this is the case, it means we have a sub expression / nested property access, such as: x.ContentType.Alias == "Test";
            // and since the sub type (x.ContentType) is not the same as x, we need to resolve a mapper for x.ContentType to get it's mapped SQL column

            // don't execute if compiled
            if (Visited == false)
            {
                var field = subMapper.Map(m.Member.Name);
                if (field.IsNullOrWhiteSpace())
                {
                    throw new InvalidOperationException(
                              $"The mapper returned an empty field for the member name: {m.Member.Name} for type: {m.Expression.Type}");
                }

                return(field);
            }

            // already compiled, return
            return(string.Empty);
        }

        // TODO: When m.Expression.NodeType == ExpressionType.Constant and it's an expression like: content => aliases.Contains(content.ContentType.Alias);
        // then an SQL parameter will be added for aliases as an array, however in SqlIn on the subclass it will manually add these SqlParameters anyways,
        // however the query will still execute because the SQL that is written will only contain the correct indexes of SQL parameters, this would be ignored,
        // I'm just unsure right now due to time constraints how to make it correct. It won't matter right now and has been working already with this bug but I've
        // only just discovered what it is actually doing.

        // TODO
        // in most cases we want to convert the value to a plain object,
        // but for in some rare cases, we may want to do it differently,
        // for instance a Models.AuditType (an enum) may in some cases
        // need to be converted to its string value.
        // but - we cannot have specific code here, really - and how would
        // we configure this? is it even possible?

        /*
         * var toString = typeof(object).GetMethod("ToString");
         * var member = Expression.Call(m, toString);
         */
        UnaryExpression member = Expression.Convert(m, typeof(object));
        var             lambda = Expression.Lambda <Func <object> >(member);
        Func <object>   getter = lambda.Compile();
        var             o      = getter();

        SqlParameters.Add(o);

        // don't execute if compiled
        if (Visited == false)
        {
            return($"@{SqlParameters.Count - 1}");
        }

        // already compiled, return
        return(string.Empty);
    }