Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Objects / ELinq / ExpressionEvaluator.cs / 3 / ExpressionEvaluator.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] //--------------------------------------------------------------------- using System.Linq.Expressions; using System.Diagnostics; using System.Reflection; using System.Linq; using System.Data.Metadata.Edm; using System.Collections.Generic; namespace System.Data.Objects.ELinq { ////// Class handling in-memory translation of expressions that are /// not supported through the standard LINQ translation. Supports /// only expressions that can be efficiently evaluated at runtime. /// internal static class ExpressionEvaluator { private static readonly IQueryProvider s_compilerQueryService = Enumerable.Empty().AsQueryable().Provider; /// /// For CompiledQuery, handles sub-expressions of the form: /// /// ctx.ObjectQueryProperty /// /// where ctx is the context parameter, e.g.: /// /// CompiledQuery.Compile((ctx, ...) => ctx...) /// /// NOTE: this method assumes that all client evaluatable nodes have been evaluated /// /// internal static bool TryEvaluateRootQuery(BindingContext bindingContext, Expression expression, out ObjectQuery rootQuery) { rootQuery = null; if (bindingContext.ObjectContext == null) { // there is no root context parameter, so the expression can't match return false; } if (!typeof(ObjectQuery).IsAssignableFrom(expression.Type)) { // if the expression doesn't return an ObjectQuery<>, it can't match the pattern return false; } Expression currentExpression = expression; // check that the remaining expression is of the form ctx.ObjectQueryProperty if (currentExpression.NodeType != ExpressionType.MemberAccess) { return false; } var memberExpression = (MemberExpression)currentExpression; currentExpression = memberExpression.Expression; if (null == currentExpression || currentExpression.NodeType != ExpressionType.Parameter) { return false; } ParameterExpression parameterExpression = (ParameterExpression)currentExpression; if (!bindingContext.IsRootContextParameter(parameterExpression)) { return false; } var queryCreator = (IRootQueryCreator)Activator.CreateInstance(typeof(RootQueryCreator<,>).MakeGenericType( parameterExpression.Type, expression.Type)); rootQuery = queryCreator.Invoke(expression, parameterExpression, bindingContext.ObjectContext); return true; } [Conditional("DEBUG")] private static void DebugOnlyVerifyMethodOverloadCount(Type type, string methodName, int expectedCount) { int count = 0; foreach (var m in type.GetMethods()) { if (m.Name == methodName) { count++; } } Debug.Assert(count == expectedCount, "Did you add a new " + methodName + " overload?"); } ////// Evaluates the given expression using the default in-memory compiler. /// /// Expression to evaluate. Must not be null. ///Result of evaluating the expression. internal static object EvaluateExpression(Expression expression) { return s_compilerQueryService.Execute(expression); } // this method is only correct when returning true // if you have also determined that all the nodes below it // also return true internal static bool IsExpressionNodeClientEvaluatable(Expression expression) { if (null == expression) { return false; } switch (expression.NodeType) { case ExpressionType.New: { // support construction of primitive types PrimitiveType primitiveType; if (!ClrProviderManifest.Instance.TryGetPrimitiveType(TypeSystem.GetNonNullableType(expression.Type), out primitiveType)) { return false; } return true; } case ExpressionType.Constant: return true; case ExpressionType.NewArrayInit: { // allow initialization of byte[] 'literals' return (typeof(byte[]) == expression.Type); } case ExpressionType.Convert: { return true; } default: return false; } } // this method is only correct when returning true // if you have also determined that all the nodes below it // also return true from (IsExpressionNodeAClosure || IsExpressionNodeClientEvaluatable) internal static bool IsExpressionNodeAClosure(Expression expression) { Debug.Assert(null != expression); if (ExpressionType.MemberAccess == expression.NodeType) { MemberExpression memberExpression = (MemberExpression)expression; if (memberExpression.Member.MemberType == MemberTypes.Property) { return !(ExpressionConverter.CanTranslatePropertyInfo((PropertyInfo)memberExpression.Member)); } return true; } return false; } private interface IRootQueryCreator { ObjectQuery Invoke(Expression body, ParameterExpression parameter, ObjectContext objectContext); } private class RootQueryCreator: IRootQueryCreator where T_Context : ObjectContext where T_ObjectQuery : ObjectQuery { public ObjectQuery Invoke(Expression body, ParameterExpression parameter, ObjectContext objectContext) { return Expression.Lambda >(body, parameter).Compile()((T_Context)objectContext); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] //--------------------------------------------------------------------- using System.Linq.Expressions; using System.Diagnostics; using System.Reflection; using System.Linq; using System.Data.Metadata.Edm; using System.Collections.Generic; namespace System.Data.Objects.ELinq { ////// Class handling in-memory translation of expressions that are /// not supported through the standard LINQ translation. Supports /// only expressions that can be efficiently evaluated at runtime. /// internal static class ExpressionEvaluator { private static readonly IQueryProvider s_compilerQueryService = Enumerable.Empty().AsQueryable().Provider; /// /// For CompiledQuery, handles sub-expressions of the form: /// /// ctx.ObjectQueryProperty /// /// where ctx is the context parameter, e.g.: /// /// CompiledQuery.Compile((ctx, ...) => ctx...) /// /// NOTE: this method assumes that all client evaluatable nodes have been evaluated /// /// internal static bool TryEvaluateRootQuery(BindingContext bindingContext, Expression expression, out ObjectQuery rootQuery) { rootQuery = null; if (bindingContext.ObjectContext == null) { // there is no root context parameter, so the expression can't match return false; } if (!typeof(ObjectQuery).IsAssignableFrom(expression.Type)) { // if the expression doesn't return an ObjectQuery<>, it can't match the pattern return false; } Expression currentExpression = expression; // check that the remaining expression is of the form ctx.ObjectQueryProperty if (currentExpression.NodeType != ExpressionType.MemberAccess) { return false; } var memberExpression = (MemberExpression)currentExpression; currentExpression = memberExpression.Expression; if (null == currentExpression || currentExpression.NodeType != ExpressionType.Parameter) { return false; } ParameterExpression parameterExpression = (ParameterExpression)currentExpression; if (!bindingContext.IsRootContextParameter(parameterExpression)) { return false; } var queryCreator = (IRootQueryCreator)Activator.CreateInstance(typeof(RootQueryCreator<,>).MakeGenericType( parameterExpression.Type, expression.Type)); rootQuery = queryCreator.Invoke(expression, parameterExpression, bindingContext.ObjectContext); return true; } [Conditional("DEBUG")] private static void DebugOnlyVerifyMethodOverloadCount(Type type, string methodName, int expectedCount) { int count = 0; foreach (var m in type.GetMethods()) { if (m.Name == methodName) { count++; } } Debug.Assert(count == expectedCount, "Did you add a new " + methodName + " overload?"); } ////// Evaluates the given expression using the default in-memory compiler. /// /// Expression to evaluate. Must not be null. ///Result of evaluating the expression. internal static object EvaluateExpression(Expression expression) { return s_compilerQueryService.Execute(expression); } // this method is only correct when returning true // if you have also determined that all the nodes below it // also return true internal static bool IsExpressionNodeClientEvaluatable(Expression expression) { if (null == expression) { return false; } switch (expression.NodeType) { case ExpressionType.New: { // support construction of primitive types PrimitiveType primitiveType; if (!ClrProviderManifest.Instance.TryGetPrimitiveType(TypeSystem.GetNonNullableType(expression.Type), out primitiveType)) { return false; } return true; } case ExpressionType.Constant: return true; case ExpressionType.NewArrayInit: { // allow initialization of byte[] 'literals' return (typeof(byte[]) == expression.Type); } case ExpressionType.Convert: { return true; } default: return false; } } // this method is only correct when returning true // if you have also determined that all the nodes below it // also return true from (IsExpressionNodeAClosure || IsExpressionNodeClientEvaluatable) internal static bool IsExpressionNodeAClosure(Expression expression) { Debug.Assert(null != expression); if (ExpressionType.MemberAccess == expression.NodeType) { MemberExpression memberExpression = (MemberExpression)expression; if (memberExpression.Member.MemberType == MemberTypes.Property) { return !(ExpressionConverter.CanTranslatePropertyInfo((PropertyInfo)memberExpression.Member)); } return true; } return false; } private interface IRootQueryCreator { ObjectQuery Invoke(Expression body, ParameterExpression parameter, ObjectContext objectContext); } private class RootQueryCreator: IRootQueryCreator where T_Context : ObjectContext where T_ObjectQuery : ObjectQuery { public ObjectQuery Invoke(Expression body, ParameterExpression parameter, ObjectContext objectContext) { return Expression.Lambda >(body, parameter).Compile()((T_Context)objectContext); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TlsSspiNegotiation.cs
- HeaderUtility.cs
- ContravarianceAdapter.cs
- XamlFigureLengthSerializer.cs
- ConnectionManagementElementCollection.cs
- Funcletizer.cs
- SimpleType.cs
- SoapDocumentServiceAttribute.cs
- UnsafeNativeMethods.cs
- ListViewContainer.cs
- KeyValueConfigurationCollection.cs
- PreservationFileReader.cs
- DataKey.cs
- ToolStripManager.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- NavigationEventArgs.cs
- TrackingServices.cs
- CodeTypeParameterCollection.cs
- XmlDataLoader.cs
- ZipIOExtraFieldElement.cs
- GlyphInfoList.cs
- EmptyCollection.cs
- DataTableMapping.cs
- KeyGestureConverter.cs
- StorageComplexPropertyMapping.cs
- TransactionInformation.cs
- StylusDownEventArgs.cs
- NotifyParentPropertyAttribute.cs
- TypeDefinition.cs
- ErrorLog.cs
- Int16.cs
- StringFunctions.cs
- LabelAutomationPeer.cs
- EntityDataSourceWrapperCollection.cs
- dtdvalidator.cs
- Root.cs
- TextDecorationCollection.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- SafeIUnknown.cs
- SelectionBorderGlyph.cs
- CookieProtection.cs
- XPathCompileException.cs
- _FtpControlStream.cs
- DataListCommandEventArgs.cs
- CodeMethodInvokeExpression.cs
- QilParameter.cs
- FixedSOMContainer.cs
- ValueQuery.cs
- PersonalizationStateInfoCollection.cs
- MultiByteCodec.cs
- ICollection.cs
- ScriptReference.cs
- EffectiveValueEntry.cs
- FilteredReadOnlyMetadataCollection.cs
- ProjectionPathBuilder.cs
- DetailsViewInsertEventArgs.cs
- RegistrationServices.cs
- TypedRowHandler.cs
- ProcessRequestArgs.cs
- XmlSchemaSubstitutionGroup.cs
- ClientRuntimeConfig.cs
- StaticTextPointer.cs
- ServiceModelSecurityTokenRequirement.cs
- AuthenticatedStream.cs
- Visual3D.cs
- Scheduling.cs
- CodePageUtils.cs
- Rect3DConverter.cs
- UpdateTranslator.cs
- WaitHandle.cs
- ArgumentOutOfRangeException.cs
- DbConnectionPoolGroup.cs
- EditBehavior.cs
- ObjectPersistData.cs
- StandardCommands.cs
- StructuralCache.cs
- RenderDataDrawingContext.cs
- OracleMonthSpan.cs
- ArraySubsetEnumerator.cs
- DbConnectionPoolIdentity.cs
- Ipv6Element.cs
- MissingFieldException.cs
- PolicyException.cs
- AssemblySettingAttributes.cs
- SwitchElementsCollection.cs
- DataBindingExpressionBuilder.cs
- ImageListUtils.cs
- SurrogateEncoder.cs
- DataBindingValueUIHandler.cs
- CodeObject.cs
- UnsafeNativeMethods.cs
- MessageDecoder.cs
- MessageQueuePermissionEntry.cs
- DataGridViewDesigner.cs
- Main.cs
- DesignerLoader.cs
- TypeNameConverter.cs
- Int16Animation.cs
- EntityDataSourceChangedEventArgs.cs
- IntSecurity.cs