• 构建一个简单的 linq to sql


     先看下运行结果:

     public class Customer<T> : IQueryable<T>, IOrderedQueryable<T>
        {
            public Customer(Expression ex, IQueryProvider Provider)
            {
                this.ElementType = typeof(T);
                this.Expression = ex;
                this.Provider = Provider;
            }
            public Customer() : this(null, new CustomerProvider())
            {
                Expression = Expression.Constant(this);
            }
            public Expression Expression { get; }
            public Type ElementType { get; }
            public IQueryProvider Provider { get; }
            public IEnumerator<T> GetEnumerator()
            {
                return (IEnumerator<T>)Provider.CreateQuery<T>(this.Expression);
            }
            IEnumerator IEnumerable.GetEnumerator()
            {
                return (IEnumerator)Provider.CreateQuery(this.Expression);
            }
            public override string ToString()
            {
                return Provider.ToString();
            }
        }
        public class CustomerProvider : IQueryProvider
        {
            private string _tableName = "";
            private string _selector = "";//查询条件
            private string _tableExName = "";//表的拓展名称
            private string _where = "";//where 语句
            private string _sql = "";
            private string _order = "";
            private int count = 0;
            Type _elementType = null;
            public IQueryable CreateQuery(Expression expression)
            {
                _elementType = expression.Type.GetGenericArguments()[0];
                GenerySql(expression);
                count++;
                object[] args = new object[] { expression, this };
                return (IQueryable)Activator.CreateInstance(typeof(Customer<>).MakeGenericType(_elementType), args);
            }
            public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
            {
                _elementType = typeof(TElement);
                _tableExName = string.Format(@"t{0}", count);
                _where = "";
                GenerySql(expression);
                count++;
                return new Customer<TElement>(expression, this);
            }
            public void GenerySql(Expression expression)
            {
                MethodCallExpression call = (MethodCallExpression)expression;
                var first = call.Arguments[0];//第一个参数
                var second = call.Arguments[1];//第二个参数
                _tableName = GetTableName(first);
                //if (first is MethodCallExpression)
                //{
                //    GenerySql(first);
                //}
                var methodName = call.Method.Name;
                if (methodName.Equals("where", StringComparison.CurrentCultureIgnoreCase))
                {
                    _selector = string.Format("select  {0}.* ", _tableExName);
                    _where += " where ";
                }
                if (methodName.Equals("orderby", StringComparison.CurrentCultureIgnoreCase))
                {
                    _selector = string.Format("select  {0}.* ", _tableExName);
                    _where += " order by ";
                }
                ProceExpress(second);
    
                _sql = string.Format(@"{0} from {1} {2}", _selector, _tableName, _where);
            }
            private void ProceExpress(Expression expression)
            {
                if (expression is UnaryExpression)
                {
                    UnaryExpression ua = (UnaryExpression)expression;
                    ProceExpress(ua.Operand);
                }
                if (expression is LambdaExpression)
                {
                    ProceExpress(((LambdaExpression)expression).Body);
                }
                if (expression is BinaryExpression)
                {
                    BinaryExpression((BinaryExpression)expression);
                }
                _where += MemberExpression(expression);
            }
            public void BinaryExpression(BinaryExpression bin)
            {
                var left = bin.Left;
                var right = bin.Right;
                var op = bin.NodeType;
                if (left is BinaryExpression)
                {
                    BinaryExpression((BinaryExpression)left);
                }
                if (op == ExpressionType.AndAlso)
                {
                    _where += " and ";
                }
                if (op == ExpressionType.OrElse)
                {
                    _where += " or ";
                }
                if (right is BinaryExpression)
                {
                    BinaryExpression((BinaryExpression)right);
                }
                _where += MemberExpression(left);
                if (op == ExpressionType.Equal)
                {
                    _where += "=";
                }
                if (right is ConstantExpression)
                {
                    var ex = (ConstantExpression)right;
                    var val = ex.Value;
                    if (ex.Type == typeof(string))
                    {
                        _where += string.Format(" '{0}' ", val);
                    }
                    else
                        _where += val;
                }
            }
            private string MemberExpression(Expression expression)
            {
                if (expression is MemberExpression)
                {
                    var b = (MemberExpression)expression;
                    return string.Format(@"{0}.{1}", _tableExName, b.Member.Name);
                }
                return string.Empty;
            }
            private string GetTableName(Expression expression)
            {
                if (expression is ConstantExpression)
                {
                    return string.Format(@"{0} as {1}", expression.Type.GetGenericArguments()[0].Name, _tableExName);
                }
                if (expression is MethodCallExpression)
                {
                    return "( " + _sql + " ) as " + _tableExName;
                }
                return "";
            }
            public object Execute(Expression expression)
            {
                return null;
            }
    
            public TResult Execute<TResult>(Expression expression)
            {
                throw new NotImplementedException();
            }
            public override string ToString()
            {
                return _sql;
            }
        }
        public class Student
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Address { get; set; }
        }
  • 相关阅读:
    USACO 1.2 Broken Necklace
    USACO 1.2 Friday the Thirteenth
    USACO 1.1 Greedy Gift Givers
    USACO 1.1 Your Ride Is Here
    CSP考试策略
    CF444A DZY Loves Physics【结论】
    树状数组-复习笔记
    CF792E Colored Balls【思维】
    USACO4.4 Shuttle Puzzle【bfs+优化】
    拓扑排序-学习笔记
  • 原文地址:https://www.cnblogs.com/student-note/p/9006615.html
Copyright © 2020-2023  润新知