构建一个简单的 linq to sql
Posted 夏风微凉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构建一个简单的 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; } }
以上是关于构建一个简单的 linq to sql的主要内容,如果未能解决你的问题,请参考以下文章