开发者

get value of a property o => o.Property1 , defined in lambda

开发者 https://www.devze.com 2023-02-03 14:50 出处:网络
I need to get the value of a property defined in a lambda public static MvcHtml开发者_开发问答String MyHelper<T, TProperty>(

I need to get the value of a property defined in a lambda

 public static MvcHtml开发者_开发问答String MyHelper<T, TProperty>(
            this HtmlHelper<T> html,
            Expression<Func<T, TProperty>> prop)
        {
            var value = \\ get the value of Prop1 (not the name "Prop1")
          ...
        }

the intended usage is something like:

public class FooViewModel 
{
    public string Prop1 { get;set; }
}

<%@ Page ViewPage<FooViewModel> %>

<%=Html.MyHelper(o => o.Prop1) %>


Why do you need expression here? If you only want to have property value, Func<T, TProperty> is sufficient - it is like any other delegate, just invoke it:

public static MvcHtmlString MyHelper<T, TProperty>(
    this HtmlHelper<T> html,
    Func<T, TProperty> prop)
{
    var obj = // ??
    var value = prop(obj); \\ get the value of Prop1 (not the name "Prop1")
    ...
}

Where obj is the object from which you want to read the value (I can't see the object around your code).


You could do it Jim's way or just do this:

public static MvcHtmlString MyHelper<T, TProperty>(
        this HtmlHelper<T> html, Expression<Func<T, TProperty>> prop)
    {
        var func = prop.Compile();
        var value = func(html.ViewData.Model);
    }


Omu,

here you go (i'm assuming you mean the actual name derived from the lambda property):

public static class ExpressionExtensions
{
    public static string GetPropertyName<TSource, TMember>(
        this Expression<Func<TSource, TMember>> memberReference)
    {
        var expression = memberReference.Body as MemberExpression;
        if (expression == null)
        {
            var convertexp = memberReference.Body as UnaryExpression;
            if (convertexp != null)
                expression = convertexp.Operand as MemberExpression; ;
        }
        if (expression == null)
            throw new ArgumentNullException("memberReference");

        return expression.Member.Name;
    }

    private static string GetPropertyName(MethodCallExpression expression)
    {
        var methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetPropertyName(methodCallExpression);
        }
        return expression.Object.ToString();
    }
}

usage:

string propertyName = prop.GetPropertyName();

enjoy..

[edit] - just saw that it's the value that you're after. here's a little bit lifted from the subsonic project that does this for you:

// 
//   SubSonic - http://subsonicproject.com
// 
//   The contents of this file are subject to the New BSD
//   License (the "License"); you may not use this file
//   except in compliance with the License. You may obtain a copy of
//   the License at http://www.opensource.org/licenses/bsd-license.php
//  
//   Software distributed under the License is distributed on an 
//   "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
//   implied. See the License for the specific language governing
//   rights and limitations under the License.
// 
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using SubSonic.Query;

namespace SubSonic.Extensions
{
    public class ExpressionParser
    {
        private const string contains = "Contains";
        private const string endsWith = "EndsWith";
        private const string nullableType = "Nullable`1";
        private const string op_Equality = "op_Equality";
        private const string op_GreaterThan = "op_GreaterThan";
        private const string op_GreaterThanOrEqual = "op_GreaterThanOrEqual";
        private const string op_LessThan = "op_LessThan";
        private const string op_LessThanOrEqual = "op_LessThanOrEqual";
        private const string startsWith = "StartsWith";
        private readonly List<Constraint> result;

        public ExpressionParser()
        {
            result = new List<Constraint>();
        }


        #region Process expressions

        /// <summary>
        /// Process the passed-in LINQ expression
        /// </summary>
        /// <param name="expression"></param>
        public List<Constraint> ProcessExpression(Expression expression)
        {
            if(expression.NodeType == ExpressionType.AndAlso)
                ProcessAndAlso((BinaryExpression)expression);
            else if(expression.NodeType == ExpressionType.NotEqual)
                BuildFromBinary(expression, Comparison.NotEquals);
            else if(expression.NodeType == ExpressionType.Equal)
                BuildFromBinary(expression, Comparison.Equals);
            else if(expression.NodeType == ExpressionType.GreaterThan)
                BuildFromBinary(expression, Comparison.GreaterThan);
            else if(expression.NodeType == ExpressionType.GreaterThanOrEqual)
                BuildFromBinary(expression, Comparison.LessOrEquals);
            else if(expression.NodeType == ExpressionType.LessThan)
                BuildFromBinary(expression, Comparison.LessThan);
            else if(expression.NodeType == ExpressionType.LessThanOrEqual)
                BuildFromBinary(expression, Comparison.LessOrEquals);
            else if(expression is MethodCallExpression)
                ProcessMethodCall((MethodCallExpression)expression);
            else if(expression is LambdaExpression)
                ProcessExpression(((LambdaExpression)expression).Body);
            //else if (expression is MethodCallExpression)
            //    ProcessMethodCall(expression as MethodCallExpression);
            return result;
        }

        private void ProcessAndAlso(BinaryExpression andAlso)
        {
            ProcessExpression(andAlso.Left);
            ProcessExpression(andAlso.Right);
        }

        private void AddConstraint(string columnName, Comparison comp, object value)
        {
            Constraint c = new Constraint(ConstraintType.Where, columnName);

            if(result.Count > 1)
                c = new Constraint(ConstraintType.And, columnName);

            //c.ParameterName = columnName;

            if(comp == Comparison.StartsWith)
            {
                value = string.Format("{0}%", value);
                comp = Comparison.Like;
            }
            else if(comp == Comparison.EndsWith)
            {
                value = string.Format("%{0}", value);
                comp = Comparison.Like;
            }

            c.Comparison = comp;
            c.ParameterValue = value;

            result.Add(c);
        }

        private void BuildFromBinary(Expression exp, Comparison op)
        {

            BinaryExpression expression = exp as BinaryExpression;

            if (expression != null)
            {
                //make sure the left side is a Member, and the right is a constant value
                if(expression.Left is MemberExpression && expression.Right is ConstantExpression)
                {
                    //the member - "Title", "Publisher", etc
                    MemberExpression memb = expression.Left as MemberExpression;
                    //the setting
                    ConstantExpression val = expression.Right as ConstantExpression;
                    AddConstraint(memb.Member.Name, op, val.Value);
                }
                    //or the left side is a Member, and the right is a conversion from a constant value to a nullable
                else if(expression.Left is MemberExpression && expression.Right.NodeType == ExpressionType.Convert
                        && expression.Right.Type.Name.Equals(nullableType))
                {
                    //the member - "Title", "Publisher", etc
                    MemberExpression memb = expression.Left as MemberExpression;
                    //the auto-conversion-to-nullable
                    UnaryExpression convert = expression.Right as UnaryExpression;
                    //the setting
                    if (convert != null)
                    {
                        ConstantExpression val = convert.Operand as ConstantExpression;
                        if(val != null)
                            AddConstraint(memb.Member.Name, op, val.Value);
                    }
                }
                    //if this isn't the case, it's Unary and is an enum setting
                else if(expression.Left.NodeType == ExpressionType.MemberAccess)
                {
                    MemberExpression left = expression.Left as MemberExpression;
                    MemberExpression right = expression.Right as MemberExpression;

                    if (right != null)
                    {
                        if (right.Expression.NodeType == ExpressionType.Constant)
                        {
                            ConstantExpression val = right.Expression as ConstantExpression;
                            if(val != null && left != null)
                            {
                                Type t = val.Value.GetType();
                                FieldInfo[] fields = t.GetFields();
                                object oVal = fields[0].GetValue(val.Value);
                                AddConstraint(left.Member.Name, op, oVal);
                            }
                        }
                        else if (right.Expression.NodeType == ExpressionType.MemberAccess)
                        {
                            //this is screwed
                            MemberExpression val = right.Expression as MemberExpression;
                            //object expressionValue = EvaluateExpression(val.Expression);
                            //expressionValue.GetType().InvokeMember(val.Member.Name, global, global, expressionValue) ;

                            var t = right.Member.MemberType;

                            //this should be a property
                            //PropertyInfo p = (PropertyInfo)t.GetProperties()[0].GetValue(right.Member, null);
                            //oVal = p.GetValue(val.Member, null);
                        }
                    }
                }
            }
        }

        private void BuildFromMemberAccess(Expression exp, Comparison op)
        {
            MethodCallExpression expression = exp as MethodCallExpression;

            if (expression != null)
            {
                if(expression.Arguments[0].NodeType == ExpressionType.MemberAccess)
                {
                    MemberExpression memberExpr = (MemberExpression)expression.Arguments[0];
                    if(expression.Arguments[1].NodeType == ExpressionType.Constant)
                    {
                        ConstantExpression val = (ConstantExpression)expression.Arguments[1];
                        AddConstraint(memberExpr.Member.Name, op, val.Value);
                    }
                }
                else if(expression.Arguments[0].NodeType == ExpressionType.Constant)
                {
                    ConstantExpression val = (ConstantExpression)expression.Arguments[0];
                    MemberExpression memberExpr = (MemberExpression)expression.Object;
                    AddConstraint(memberExpr.Member.Name, op, val.Value);
                }
            }
        }

        private void ProcessMethodCall(MethodCallExpression expression)
        {
            switch(expression.Method.Name)
            {
                case op_Equality:
                    // Handle book.Publisher == "xxx"
                    BuildFromMemberAccess(expression, Comparison.Equals);
                    break;
                case op_GreaterThan:
                    // Handle book.Price <= xxx
                    BuildFromMemberAccess(expression, Comparison.GreaterThan);
                    break;
                case op_LessThan:
                    // Handle book.Price <= xxx
                    BuildFromMemberAccess(expression, Comparison.LessThan);
                    break;
                case op_LessThanOrEqual:
                    // Handle book.Price <= xxx
                    BuildFromMemberAccess(expression, Comparison.LessOrEquals);
                    break;
                case op_GreaterThanOrEqual:
                    // Handle book.Price <= xxx
                    BuildFromMemberAccess(expression, Comparison.GreaterOrEquals);
                    break;
                case contains:
                    BuildFromMemberAccess(expression, Comparison.Like);
                    break;
                case startsWith:
                    BuildFromMemberAccess(expression, Comparison.StartsWith);
                    break;
                case endsWith:
                    // Handle book.Title.Contains("xxx")
                    BuildFromMemberAccess(expression, Comparison.EndsWith);
                    break;
            }
        }

        #endregion Process expressions
    }
}

usage:

private static string ParseExpression(Expression<Func<T, bool>> expression)
{
    var parse = new SubSonic.Extensions.ExpressionParser();
    IList expList = parse.ProcessExpression(expression);
    string expressionParsed = "";
    foreach (SubSonic.Query.Constraint s in expList)
    {
        expressionParsed += string.Format("{0}.{1}.{2}", s.ColumnName, s.Comparison, s.ParameterValue);
    }
    return expressionParsed;
}

tha above ParseExpression() should allow you to find out most anything you need about your Expression.


Omu,

Darn the 30k limit here :). had to add the constrint class as a seperate answer. grr..

// 
//   SubSonic - http://subsonicproject.com
// 
//   The contents of this file are subject to the New BSD
//   License (the "License"); you may not use this file
//   except in compliance with the License. You may obtain a copy of
//   the License at http://www.opensource.org/licenses/bsd-license.php
//  
//   Software distributed under the License is distributed on an 
//   "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
//   implied. See the License for the specific language governing
//   rights and limitations under the License.
// 
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using SubSonic.Extensions;

namespace SubSonic.Query
{
    /// <summary>
    /// Where, And, Or
    /// </summary>
    public enum ConstraintType
    {
        /// <summary>
        /// WHERE operator
        /// </summary>
        Where,
        /// <summary>
        /// AND operator
        /// </summary>
        And,
        /// <summary>
        /// OR Operator
        /// </summary>
        Or
    }


    /// <summary>
    /// SQL Comparison Operators
    /// </summary>
    public enum Comparison
    {
        Equals,
        NotEquals,
        Like,
        NotLike,
        GreaterThan,
        GreaterOrEquals,
        LessThan,
        LessOrEquals,
        Blank,
        Is,
        IsNot,
        In,
        NotIn,
        OpenParentheses,
        CloseParentheses,
        BetweenAnd,
        StartsWith,
        EndsWith
    }


    /// <summary>
    /// Summary for the SqlComparison class
    /// </summary>
    public class SqlComparison
    {
        public const string BLANK = " ";
        public const string EQUAL = " = ";
        public const string GREATER = " > ";
        public const string GREATER_OR_EQUAL = " >= ";
        public const string IS = " IS ";
        public const string IS_NOT = " IS NOT ";
        public const string LESS = " < ";
        public const string LESS_OR_EQUAL = " <= ";
        public const string LIKE = " LIKE ";
        public const string NOT_EQUAL = " <> ";
        public const string NOT_LIKE = " NOT LIKE ";
    }

    /// <summary>
    /// A Class for handling SQL Constraint generation
    /// </summary>
    public class Constraint
    {
        /// <summary>
        /// The query that this constraint is operating on
        /// </summary>
        public SqlQuery query;

        public Constraint() {}


        #region Factory methods

        /// <summary>
        /// Initializes a new instance of the <see cref="Constraint"/> class.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="constraintColumnName">Name of the constraint column.</param>
        public Constraint(ConstraintType condition, string constraintColumnName)
        {
            Condition = condition;
            ColumnName = constraintColumnName;
            QualifiedColumnName = constraintColumnName;
            ConstructionFragment = constraintColumnName;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Constraint"/> class.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="constraintColumnName">Name of the constraint column.</param>
        /// <param name="constraintQualifiedColumnName">Name of the constraint qualified column.</param>
        public Constraint(ConstraintType condition, string constraintColumnName, string constraintQualifiedColumnName)
        {
            Condition = condition;
            ColumnName = constraintColumnName;
            QualifiedColumnName = constraintQualifiedColumnName;
            ConstructionFragment = constraintColumnName;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Constraint"/> class.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="constraintColumnName">Name of the constraint column.</param>
        /// <param name="constraintQualifiedColumnName">Name of the constraint qualified column.</param>
        /// <param name="constraintConstructionFragment">The constraint construction fragment.</param>
        public Constraint(ConstraintType condition, string constraintColumnName, string constraintQualifiedColumnName, string constraintConstructionFragment)
        {
            Condition = condition;
            ColumnName = constraintColumnName;
            QualifiedColumnName = constraintQualifiedColumnName;
            ConstructionFragment = constraintConstructionFragment;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Constraint"/> class.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="constraintColumnName">Name of the constraint column.</param>
        /// <param name="sqlQuery">The SQL query.</param>
        public Constraint(ConstraintType condition, string constraintColumnName, SqlQuery sqlQuery)
        {
            Condition = condition;
            ColumnName = constraintColumnName;
            QualifiedColumnName = constraintColumnName;
            ConstructionFragment = constraintColumnName;
            query = sqlQuery;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Constraint"/> class.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="constraintColumnName">Name of the constraint column.</param>
        /// <param name="constraintQualifiedColumnName">Name of the constraint qualified column.</param>
        /// <param name="constraintConstructionFragment">The constraint construction fragment.</param>
        /// <param name="sqlQuery">The SQL query.</param>
        public Constraint(ConstraintType condition, string constraintColumnName, string constraintQualifiedColumnName, string constraintConstructionFragment, SqlQuery sqlQuery)
        {
            Condition = condition;
            ColumnName = constraintColumnName;
            QualifiedColumnName = constraintQualifiedColumnName;
            ConstructionFragment = constraintConstructionFragment;
            query = sqlQuery;
        }

        /// <summary>
        /// Wheres the specified column name.
        /// </summary>
        /// <param name="columnName">Name of the column.</param>
        /// <returns></returns>
        public static Constraint Where(string columnName)
        {
            return new Constraint(ConstraintType.Where, columnName);
        }

        /// <summary>
        /// Ands the specified column name.
        /// </summary>
        /// <param name="columnName">Name of the column.</param>
        /// <returns></returns>
        public static Constraint And(string columnName)
        {
            return new Constraint(ConstraintType.And, columnName);
        }

        /// <summary>
        /// Ors the specified column name.
        /// </summary>
        /// <param name="columnName">Name of the column.</param>
        /// <returns></returns>
        public static Constraint Or(string columnName)
        {
            return new Constraint(ConstraintType.Or, columnName);
        }

        #endregion


        #region props

        /// <summary>
        /// Gets or sets the name of the table.
        /// </summary>
        /// <value>The name of the table.</value>
        private string _tableName = String.Empty;

        private ConstraintType condition = ConstraintType.Where;
        private string parameterName;

        /// <summary>
        /// Gets or sets the condition.
        /// </summary>
        /// <value>The condition.</value>
        public ConstraintType Condition
        {
            get { return condition; }
            set { condition = value; }
        }

        public string TableName
        {
            get { return _tableName; }
            set { _tableName = value; }
        }

        /// <summary>
        /// Gets or sets the name of the column.
        /// </summary>
        /// <value>The name of the column.</value>
        public string ColumnName { get; set; }

        /// <summary>
        /// Gets or sets the fully qualified name of the column.
        /// </summary>
        /// <value>The name of the column.</value>
        public string QualifiedColumnName { get; set; }

        /// <summary>
        /// Gets or sets the string fragment used when assembling the text of query.
        /// </summary>
        /// <value>The construction fragment.</value>
        public string ConstructionFragment { get; set; }

        /// <summary>
        /// Gets or sets the comparison.
        /// </summary>
        /// <value>The comparison.</value>
        public Comparison Comparison { get; set; }

        /// <summary>
        /// Gets or sets the parameter value.
        /// </summary>
        /// <value>The parameter value.</value>
        public object ParameterValue { get; set; }

        /// <summary>
        /// Gets or sets the start value.
        /// </summary>
        /// <value>The start value.</value>
        public object StartValue { get; set; }

        /// <summary>
        /// Gets or sets the end value.
        /// </summary>
        /// <value>The end value.</value>
        public object EndValue { get; set; }

        /// <summary>
        /// Gets or sets the in values.
        /// </summary>
        /// <value>The in values.</value>
        public IEnumerable InValues { get; set; }

        /// <summary>
        /// Gets or sets the in select.
        /// </summary>
        /// <value>The in select.</value>
        public SqlQuery InSelect { get; set; }

        /// <summary>
        /// Gets or sets the name of the parameter.
        /// </summary>
        /// <value>The name of the parameter.</value>
        public string ParameterName
        {
            get { return parameterName ?? ColumnName; }
            set { parameterName = value; }
        }

        /// <summary>
        /// Gets or sets the type of the db.
        /// </summary>
        /// <value>The type of the db.</value>
        public DbType DbType { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this constraint is an Aggregate.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is aggregate; otherwise, <c>false</c>.
        /// </value>
        public bool IsAggregate { get; set; }

        /// <summary>
        /// Gets the comparison operator.
        /// </summary>
        /// <param name="comp">The comp.</param>
        /// <returns></returns>
        public static string GetComparisonOperator(Comparison comp)
        {
            string sOut;
            switch(comp)
            {
                case Comparison.Blank:
                    sOut = SqlComparison.BLANK;
                    break;
                case Comparison.GreaterThan:
                    sOut = SqlComparison.GREATER;
                    break;
                case Comparison.GreaterOrEquals:
                    sOut = SqlComparison.GREATER_OR_EQUAL;
                    break;
                case Comparison.LessThan:
                    sOut = SqlComparison.LESS;
                    break;
                case Comparison.LessOrEquals:
                    sOut = SqlComparison.LESS_OR_EQUAL;
                    break;
                case Comparison.Like:
                    sOut = SqlComparison.LIKE;
                    break;
                case Comparison.NotEquals:
                    sOut = SqlComparison.NOT_EQUAL;
                    break;
                case Comparison.NotLike:
                    sOut = SqlComparison.NOT_LIKE;
                    break;
                case Comparison.Is:
                    sOut = SqlComparison.IS;
                    break;
                case Comparison.IsNot:
                    sOut = SqlComparison.IS_NOT;
                    break;
                case Comparison.OpenParentheses:
                    sOut = "(";
                    break;
                case Comparison.CloseParentheses:
                    sOut = ")";
                    break;
                case Comparison.In:
                    sOut = " IN ";
                    break;
                case Comparison.NotIn:
                    sOut = " NOT IN ";
                    break;
                default:
                    sOut = SqlComparison.EQUAL;
                    break;
            }
            return sOut;
        }

        #endregion


        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals(object obj)
        {
            if(obj is Constraint)
            {
                Constraint compareTo = (Constraint)obj;
                return compareTo.ParameterName.Matches(parameterName) &&
                       compareTo.ParameterValue.Equals(ParameterValue);
            }
            return base.Equals(obj);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Creates a LIKE statement.
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery Like(string val)
        {
            Comparison = Comparison.Like;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);

            return query;
        }

        /// <summary>
        /// Creates a LIKE statement and appends a wildcard to the end of the passed-in value.
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery StartsWith(string val)
        {
            return StartsWith(val, "%");
        }

        public SqlQuery StartsWith(string val, string wildCard)
        {
            Comparison = Comparison.Like;
            ParameterValue = String.Format("{0}{1}", val, wildCard);
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);

            return query;
        }

        /// <summary>
        /// Creates a LIKE statement and appends a wildcard to the end of the passed-in value.
        /// </summary>
        /// <param name="val">The val.</param>
        /// <param name="wildCard">The wild card.</param>
        /// <returns></returns>
        public SqlQuery EndsWith(string val, string wildCard)
        {
            Comparison = Comparison.Like;
            ParameterValue = String.Format("{0}{1}", wildCard, val);
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);

            return query;
        }

        /// <summary>
        /// Creates a LIKE statement and appends a wildcard to the end of the passed-in value.
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery EndsWith(string val)
        {
            return EndsWith(val, "%");
        }

        /// <summary>
        /// Creates a NOT LIKE statement
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery NotLike(string val)
        {
            Comparison = Comparison.NotLike;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);

            return query;
        }

        /// <summary>
        /// Determines whether [is greater than] [the specified val].
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery IsGreaterThan(object val)
        {
            Comparison = Comparison.GreaterThan;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);

            return query;
        }

        /// <summary>
        /// Determines whether [is greater than] [the specified val].
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery IsGreaterThanOrEqualTo(object val)
        {
            Comparison = Comparison.GreaterOrEquals;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);

            return query;
        }

        /// <summary>
        /// Specifies a SQL IN statement using a nested Select statement
        /// </summary>
        /// <param name="selectQuery">The select query.</param>
        /// <returns></returns>
        public SqlQuery In(SqlQuery selectQuery)
        {
            //validate that there is only one column in the columnlist
            if(selectQuery.SelectColumnList.Length == 0 || selectQuery.SelectColumnList.Length > 1)
                throw new InvalidOperationException("You must specify a column to return for the IN to be valid. Use Select(\"column\") to do this");

            InSelect = selectQuery;

            Comparison = Comparison.In;
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Specifies a SQL IN statement
        /// </summary>
        /// <param name="vals">Value array</param>
        /// <returns></returns>
        public SqlQuery In(IEnumerable vals)
        {
            InValues = vals;
            Comparison = Comparison.In;
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Specifies a SQL IN statement
        /// </summary>
        /// <param name="vals">Value array</param>
        /// <returns></returns>
        public SqlQuery In(params object[] vals)
        {
            InValues = vals;
            Comparison = Comparison.In;
            query.Constraints.Add(this);
            return query;
            //this is trickery, since every time we send in a Select query, it will call this method
            //so we need to evaluate it, and call In(Select)
            //I don't like this hack, but don't see a way around it
            /*
            if(vals.Length > 0)
            {
                if(vals[0].ToString().StartsWith("SELECT"))
                {
                    Select s = (Select)vals[0];
                    query = In(s);
                }
                else
                {
                    InValues = vals;
                    Comparison = Comparison.In;
                    query.Constraints.Add(this);
                }
            }

            return query;*/
        }

        /// <summary>
        /// Specifies a SQL IN statement using a nested Select statement
        /// </summary>
        /// <param name="selectQuery">The select query.</param>
        /// <returns></returns>
        public SqlQuery NotIn(SqlQuery selectQuery)
        {
            //validate that there is only one column in the columnlist
            if(selectQuery.SelectColumnList.Length == 0 || selectQuery.SelectColumnList.Length > 1)
                throw new InvalidOperationException("You must specify a column to return for the IN to be valid. Use Select(\"column\") to do this");

            InSelect = selectQuery;

            Comparison = Comparison.NotIn;
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Specifies a SQL Not IN statement
        /// </summary>
        /// <param name="vals">Value array</param>
        /// <returns></returns>
        public SqlQuery NotIn(IEnumerable vals)
        {
            InValues = vals;
            Comparison = Comparison.NotIn;
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Specifies a SQL NOT IN statement
        /// </summary>
        /// <param name="vals">Value array</param>
        /// <returns></returns>
        public SqlQuery NotIn(params object[] vals)
        {
            InValues = vals;
            Comparison = Comparison.NotIn;
            query.Constraints.Add(this);
            return query;
                /*
            if(vals.Length > 0)
            {
                if(vals[0].ToString().StartsWith("SELECT"))
                {
                    Select s = (Select)vals[0];
                    query = NotIn(s);
                }
                else
                {
                    InValues = vals;
                    Comparison = Comparison.NotIn;
                    query.Constraints.Add(this);
                }
            }
            return query;*/
        }

        /// <summary>
        /// Determines whether [is less than] [the specified val].
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery IsLessThan(object val)
        {
            Comparison = Comparison.LessThan;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Determines whether [is less than] [the specified val].
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery IsLessThanOrEqualTo(object val)
        {
            Comparison = Comparison.LessOrEquals;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Determines whether [is not null] [the specified val].
        /// </summary>
        /// <returns></returns>
        public SqlQuery IsNotNull()
        {
            Comparison = Comparison.IsNot;
            ParameterValue = DBNull.Value;
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Determines whether the specified val is null.
        /// </summary>
        /// <returns></returns>
        public SqlQuery IsNull()
        {
            Comparison = Comparison.Is;
            ParameterValue = DBNull.Value;
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Determines whether [is between and] [the specified val1].
        /// </summary>
        /// <param name="val1">The val1.</param>
        /// <param name="val2">The val2.</param>
        /// <returns></returns>
        public SqlQuery IsBetweenAnd(object val1, object val2)
        {
            Comparison = Comparison.BetweenAnd;
            StartValue = val1;
            EndValue = val2;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val1);
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Determines whether [is equal to] [the specified val].
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery IsEqualTo(object val)
        {
            Comparison = Comparison.Equals;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);
            return query;
        }

        /// <summary>
        /// Determines whether [is not equal to] [the specified val].
        /// </summary>
        /// <param name="val">The val.</param>
        /// <returns></returns>
        public SqlQuery IsNotEqualTo(object val)
        {
            Comparison = Comparison.NotEquals;
            ParameterValue = val;
            DbType = query.GetConstraintDbType(TableName, ColumnName, val);
            query.Constraints.Add(this);
            return query;
        }
    }
}

join with previous answer and cook for 2 seconds... sorry this 'answer' is so verbose, this is all normally wrapped in subsonic, so is a one liner for me.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号