珂珂的个人博客 - 一个程序猿的个人网站

自己来实现linq查询(三)

自己来实现linq查询(一)

自己来实现linq查询(二)

自己来实现linq查询(三)

最后一篇把剩下的类都贴出来,之后会放上源码下载

QueryProviderAbstract类


using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace FYJ.Data.Linq
{
    public abstract class QueryProviderAbstract : IQueryProvider
    {
       protected Type elementType;
       protected FYJ.Data.IDbHelper db;
       protected QueryProviderAbstract(Type elementType, IDbHelper db = null)
       {
           this.elementType = elementType;
           this.db = db;
       }

        #region IQueryProvider 成员

        public IQueryableCreateQuery(System.Linq.Expressions.Expression expression)
        {
            return new DbQueryable(this, expression);
        }

        public IQueryable CreateQuery(System.Linq.Expressions.Expression expression)
        {

          Type  elementType = TypeSystem.GetElementType(expression.Type);
            try
            {
                return (IQueryable)Activator.CreateInstance(
                    typeof(DbQueryable<>).MakeGenericType(elementType),
                    new object[] { this, expression });
            }
            catch (TargetInvocationException tie) 
            {
                throw tie.InnerException;
            }
        }

        T IQueryProvider.Execute(System.Linq.Expressions.Expression expression)
        {
            return (T)this.Execute(expression);
        }

        object IQueryProvider.Execute(System.Linq.Expressions.Expression expression)
        {
            return this.Execute(expression);
        }

   
        public object Execute(Expression expression)
        {
            TranslateResult result = new QueryExpressionVisitor(this.elementType, db).Translate(expression);
            string sql = result.CommandText;
            DataTable dt = ExecuteDataTable(sql);
            Type elementType = TypeSystem.GetElementType(expression.Type);

            if (result.Prsojector != null)
            {
                Delegate projector = result.Prsojector.Compile();
                return Activator.CreateInstance(
                    typeof(ObjectReader<>).MakeGenericType(elementType),
                    BindingFlags.Instance | BindingFlags.NonPublic, null,
                    new object[] { dt, projector },
                    null
                    );
            }
            else
            {
                return Activator.CreateInstance(
                    typeof(ObjectReader<>).MakeGenericType(elementType),
                    BindingFlags.Instance | BindingFlags.NonPublic, null,
                    new object[] { dt },
                    null
                    );
            }
        }

        public abstract DataTable ExecuteDataTable(string sql);
        #endregion
    }
}

TranslateResult类



using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace FYJ.Data.Linq
{
    internal class TranslateResult
    {
        internal string CommandText;
        internal LambdaExpression Prsojector;
    }
}

TypeSystem 类



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FYJ.Data.Linq
{
    internal static class TypeSystem
    {
        internal static Type GetElementType(Type seqType)
        {
            Type ienum = FindIEnumerable(seqType);
            if (ienum == null) return seqType;
            return ienum.GetGenericArguments()[0];
        }

        private static Type FindIEnumerable(Type seqType)
        {
            if (seqType == null || seqType == typeof(string))
                return null;

            if (seqType.IsArray)
                return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());

            if (seqType.IsGenericType)
            {
                foreach (Type arg in seqType.GetGenericArguments())
                {
                    Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);
                    if (ienum.IsAssignableFrom(seqType))
                    {
                        return ienum;
                    }
                }
            }

            Type[] ifaces = seqType.GetInterfaces();
            if (ifaces != null && ifaces.Length > 0)
            {
                foreach (Type iface in ifaces)
                {
                    Type ienum = FindIEnumerable(iface);
                    if (ienum != null) return ienum;
                }
            }

            if (seqType.BaseType != null && seqType.BaseType != typeof(object))
            {
                return FindIEnumerable(seqType.BaseType);
            }

            return null;
        }
    }
}



上一篇:URL 签名验证

下一篇:个人代码全部开源


0 评论

查看所有评论

给个评论吧