最后一篇把剩下的类都贴出来,之后会放上源码下载
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; } } }