最后一篇把剩下的类都贴出来,之后会放上源码下载
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;
}
}
}
珂珂的个人博客 - 一个程序猿的个人网站