IQueryable IQueryProvider.CreateQuery(Expression expression) { var elementType = ExpressionUtility.ElementType(expression); var queryable = CreateQuery(expression, elementType); return(queryable); }
protected override Expression VisitMethodCall(MethodCallExpression m) { var anonymousType = typeof(DataRow); if (m.Method.Name == "Cast") { var castSourceType = ExpressionUtility.ElementType(m.Arguments[0]); var castTargetType = ExpressionUtility.ElementType(m); if (castTargetType.IsAssignableFrom(anonymousType)) { this.typePaires.Add(castSourceType, castTargetType); } } return(base.VisitMethodCall(m)); }
TResult IQueryProvider.Execute <TResult>(Expression expression) { expression = UpdateExpression(expression); var isSingleValue = !typeof(IEnumerable).IsAssignableFrom(expression.Type) || expression.Type == typeof(string); if (isSingleValue) { var obj = this.source.Execute <TResult>(expression); return(obj); } var castSourceType = ExpressionUtility.ElementType(expression); var castTargetType = GetElementType(typeof(TResult)); if (castSourceType != castTargetType) { expression = Expression.Call(typeof(Queryable), "Cast", new[] { castTargetType }, expression); } var items = this.source.Execute <TResult>(expression); return(items); }
protected override Expression VisitMethodCall(MethodCallExpression m) { //============================================================== // 说明:将索引器字段转换为类的属性或字段 if (m.Method.Name == "get_Item" && m.Object != null && m.Object.Type == this.oldType) { Debug.Assert(m.Arguments.Count == 1); var arg = m.Arguments[0]; Debug.Assert(arg.NodeType == ExpressionType.Constant); Debug.Assert(arg.Type == typeof(string)); var name = (string)((ConstantExpression)arg).Value; var pf = TypeUtility.FindPropertyOrField(this.newType, name, false); if (pf == null) { throw Error.NoPublicPropertyOrField(name, newType); } Expression expr = Expression.MakeMemberAccess(this.parameter, pf); if (m.Type != expr.Type) { expr = Expression.Convert(expr, m.Type); } return(expr); } //============================================================== //============================================================== // 说明:如果序列的实际类型与 Cast 的目标类型一致,则直接返回序列,而不进行转换。 // 例如: // var q = db.CreateQuery("select p from Products as p").Cast<Product>(); // 由于序列的实际类型即是Product,因为,Cast 是多余的,直接除。即变为: // db.CreateQuery("select p from Products as p") //-------------------------------------------------------------- if (m.Method.Name == "Cast") { var castSourceType = ExpressionUtility.ElementType(m.Arguments[0]); var castTargetType = ExpressionUtility.ElementType(m); if (this.newType == castSourceType && this.oldType == castTargetType) { return(m.Arguments[0]); } } //============================================================== Expression instance = Visit(m.Object); IEnumerable <Expression> arguments = VisitExpressionList(m.Arguments); if ((instance == m.Object) && (arguments == m.Arguments)) { return(m); } //============================================================== // 说明:替换掉原来的类型 // 例如: // var q = db.CreateQuery<IDataRecord>("select p from Products as p") // 变为 // q = db.CreateQuery<Product>() if (m.Method.IsGenericMethod) { var argTypes = m.Method.GetGenericArguments(); if (argTypes[0] == oldType) { var methodName = m.Method.Name; var declareType = m.Method.DeclaringType; argTypes[0] = newType; var expr = Expression.Call(declareType, methodName, argTypes, arguments.ToArray()); return(expr); } } //============================================================== return(Expression.Call(instance, m.Method, arguments)); }