Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Objects / ELinq / ELinqQueryState.cs / 1 / ELinqQueryState.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq { using System; using System.Collections.Generic; using System.Data.Common.CommandTrees; using System.Data.Metadata.Edm; using System.Data.Objects; using System.Data.Objects.ELinq; using System.Data.Objects.Internal; using System.Diagnostics; using System.Reflection; using CqtExpression = System.Data.Common.CommandTrees.DbExpression; using LinqExpression = System.Linq.Expressions.Expression; ////// Models a Linq to Entities ObjectQuery /// internal class ELinqQueryState : ObjectQueryState { #region Private State private readonly LinqExpression _expression; private List_closureBindings; #endregion #region Constructors /// /// Constructs a new ELinqQueryImplementation based on the specified Linq Expression /// against the specified ObjectContext. /// /// The element type of the implemented ObjectQuery, as a CLR type. /// The ObjectContext with which the implemented ObjectQuery is associated. /// The Linq Expression that defines this query. internal ELinqQueryState(Type elementType, ObjectContext context, LinqExpression expression) : this(elementType, context, null, expression) { } ////// Constructs a new ELinqQueryImplementation based on the specified Linq Expression /// against the specified ObjectContext. /// /// The element type of the implemented ObjectQuery, as a CLR type. /// The ObjectContext with which the implemented ObjectQuery is associated. /// The Linq Expression that defines this query. /// The parameters referenced by the implemented ObjectQuery. protected ELinqQueryState(Type elementType, ObjectContext context, ObjectParameterCollection parameters, LinqExpression expression) : base(elementType, context, parameters, null) { // // Initialize the LINQ expression, which is passed in via // public APIs on ObjectQuery and must be checked here // (the base class performs similar checks on the ObjectContext and MergeOption arguments). // EntityUtil.CheckArgumentNull(expression, "expression"); // closure bindings and initializers are explicitly allowed to be null _expression = expression; } #endregion #region ObjectQueryState overrides protected override TypeUsage GetResultType() { // Since this method is only called once, on demand, a full conversion pass // is performed to produce the DbExpression and return its result type. // This does not affect any cached execution plan or closure bindings that may be present. ExpressionConverter converter = this.CreateExpressionConverter(); return converter.Convert().ResultType; } internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption) { Debug.Assert(this.Span == null, "Include span specified on compiled LINQ-based ObjectQuery instead of within the expression tree?"); // If this query has already been prepared, its current execution plan may no longer be valid. ObjectQueryExecutionPlan plan = this._cachedPlan; if (plan != null) { // Was a merge option specified in the call to Execute(MergeOption) or set via ObjectQuery.MergeOption? MergeOption? explicitMergeOption = GetMergeOption(forMergeOption, this.UserSpecifiedMergeOption); // If a merge option was explicitly specified, and it does not match the plan's merge option, then the plan is no longer valid. if(explicitMergeOption.HasValue && explicitMergeOption.Value != plan.MergeOption) { plan = null; } else if (this._closureBindings != null) { // No merge option was specified; the plan's merge option is either the propagated merge option from a referenced query // or it is the global default merge option, so the plan is considered invalid if any closure binding changed - which includes // detecting whether a merge option was changed on a referenced query. bool planInvalid = false; foreach (ClosureBinding binding in this._closureBindings) { planInvalid |= binding.EvaluateBinding(); } if (planInvalid) { plan = null; } } } // The plan may have been invalidated above, or this query may never have been prepared. if (plan == null) { // Metadata is required to generate the execution plan. this.ObjectContext.EnsureMetadata(); // Reset internal state this._closureBindings = null; this.ResetParameters(); // Translate LINQ expression to a DbExpression ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); DbQueryCommandTree tree = (DbQueryCommandTree)queryExpression.CommandTree; tree.Query = queryExpression; // Retrieve the new set of closure bindings from the converter this._closureBindings = converter.ClosureBindings; // Determine the merge option, with the following precedence: // 1. A merge option was specified explicitly as the argument to Execute(MergeOption). // 2. The user has set the MergeOption property on the ObjectQuery instance. // 3. A merge option has been extracted from the 'root' query and propagated to the root of the expression tree. // 4. The global default merge option. MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, converter.PropagatedMergeOption); // If parameters were aggregated from referenced (non-LINQ) ObjectQuery instances then add them to the parameters collection if (converter.Parameters != null && converter.Parameters.Count > 0) { ObjectParameterCollection currentParams = this.EnsureParameters(); currentParams.SetReadOnly(false); foreach (ObjectParameter convertedParam in converter.Parameters) { // Note that it is safe to add the parameter directly only // because parameters are cloned before they are added to the // converter's parameter collection, or they came from this // instance's parameter collection in the first place. currentParams.Add(convertedParam); } currentParams.SetReadOnly(true); } plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan); this._cachedPlan = plan; } if (this.Parameters != null) { this.Parameters.SetReadOnly(true); } return plan; } ////// Returns a new ObjectQueryState instance with the specified navigation property path specified as an Include span. /// For eLINQ queries the Include operation is modelled as a method call expression applied to the source ObectQuery, /// so the ///property is always null on the returned instance. ///The element type of the resulting query /// The ObjectQuery on which Include was called; required to build the new method call expression /// The new Include path ///A new ObjectQueryState instance that incorporates the Include path, in this case a new method call expression internal override ObjectQueryState Include(ObjectQuery sourceQuery, string includePath) { MethodInfo includeMethod = sourceQuery.GetType().GetMethod("Include", BindingFlags.Public | BindingFlags.Instance); Debug.Assert(includeMethod != null, "Unable to find ObjectQuery.Include method?"); LinqExpression includeCall = LinqExpression.Call(LinqExpression.Constant(sourceQuery), includeMethod, new LinqExpression[] { LinqExpression.Constant(includePath, typeof(string)) }); ObjectQueryState retState = new ELinqQueryState(this.ElementType, this.ObjectContext, includeCall); this.ApplySettingsTo(retState); return retState; } /// /// eLINQ queries do not have command text. This method always returns /// Always set tofalse . ///null ///Always returns internal override bool TryGetCommandText(out string commandText) { commandText = null; return false; } ///false /// Gets the LINQ Expression that defines this query for external (of ObjectQueryState) use. /// Note that the /// The LINQ expression that describes this query ///property is used, which is overridden by compiled eLINQ /// queries to produce an Expression tree where parameter references have been replaced with constants. /// Always returns internal override bool TryGetExpression(out System.Linq.Expressions.Expression expression) { expression = this.Expression; return true; } #endregion internal virtual LinqExpression Expression { get { return _expression; } } protected virtual ExpressionConverter CreateExpressionConverter() { DbQueryCommandTree tree = new DbQueryCommandTree(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace); return new ExpressionConverter(this.ObjectContext, new BindingContext(), tree, _expression, null); } private void ResetParameters() { if (this.Parameters != null) { bool wasLocked = ((ICollectiontrue )this.Parameters).IsReadOnly; if (wasLocked) { this.Parameters.SetReadOnly(false); } this.Parameters.Clear(); if (wasLocked) { this.Parameters.SetReadOnly(true); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.Objects.ELinq { using System; using System.Collections.Generic; using System.Data.Common.CommandTrees; using System.Data.Metadata.Edm; using System.Data.Objects; using System.Data.Objects.ELinq; using System.Data.Objects.Internal; using System.Diagnostics; using System.Reflection; using CqtExpression = System.Data.Common.CommandTrees.DbExpression; using LinqExpression = System.Linq.Expressions.Expression; ////// Models a Linq to Entities ObjectQuery /// internal class ELinqQueryState : ObjectQueryState { #region Private State private readonly LinqExpression _expression; private List_closureBindings; #endregion #region Constructors /// /// Constructs a new ELinqQueryImplementation based on the specified Linq Expression /// against the specified ObjectContext. /// /// The element type of the implemented ObjectQuery, as a CLR type. /// The ObjectContext with which the implemented ObjectQuery is associated. /// The Linq Expression that defines this query. internal ELinqQueryState(Type elementType, ObjectContext context, LinqExpression expression) : this(elementType, context, null, expression) { } ////// Constructs a new ELinqQueryImplementation based on the specified Linq Expression /// against the specified ObjectContext. /// /// The element type of the implemented ObjectQuery, as a CLR type. /// The ObjectContext with which the implemented ObjectQuery is associated. /// The Linq Expression that defines this query. /// The parameters referenced by the implemented ObjectQuery. protected ELinqQueryState(Type elementType, ObjectContext context, ObjectParameterCollection parameters, LinqExpression expression) : base(elementType, context, parameters, null) { // // Initialize the LINQ expression, which is passed in via // public APIs on ObjectQuery and must be checked here // (the base class performs similar checks on the ObjectContext and MergeOption arguments). // EntityUtil.CheckArgumentNull(expression, "expression"); // closure bindings and initializers are explicitly allowed to be null _expression = expression; } #endregion #region ObjectQueryState overrides protected override TypeUsage GetResultType() { // Since this method is only called once, on demand, a full conversion pass // is performed to produce the DbExpression and return its result type. // This does not affect any cached execution plan or closure bindings that may be present. ExpressionConverter converter = this.CreateExpressionConverter(); return converter.Convert().ResultType; } internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption) { Debug.Assert(this.Span == null, "Include span specified on compiled LINQ-based ObjectQuery instead of within the expression tree?"); // If this query has already been prepared, its current execution plan may no longer be valid. ObjectQueryExecutionPlan plan = this._cachedPlan; if (plan != null) { // Was a merge option specified in the call to Execute(MergeOption) or set via ObjectQuery.MergeOption? MergeOption? explicitMergeOption = GetMergeOption(forMergeOption, this.UserSpecifiedMergeOption); // If a merge option was explicitly specified, and it does not match the plan's merge option, then the plan is no longer valid. if(explicitMergeOption.HasValue && explicitMergeOption.Value != plan.MergeOption) { plan = null; } else if (this._closureBindings != null) { // No merge option was specified; the plan's merge option is either the propagated merge option from a referenced query // or it is the global default merge option, so the plan is considered invalid if any closure binding changed - which includes // detecting whether a merge option was changed on a referenced query. bool planInvalid = false; foreach (ClosureBinding binding in this._closureBindings) { planInvalid |= binding.EvaluateBinding(); } if (planInvalid) { plan = null; } } } // The plan may have been invalidated above, or this query may never have been prepared. if (plan == null) { // Metadata is required to generate the execution plan. this.ObjectContext.EnsureMetadata(); // Reset internal state this._closureBindings = null; this.ResetParameters(); // Translate LINQ expression to a DbExpression ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); DbQueryCommandTree tree = (DbQueryCommandTree)queryExpression.CommandTree; tree.Query = queryExpression; // Retrieve the new set of closure bindings from the converter this._closureBindings = converter.ClosureBindings; // Determine the merge option, with the following precedence: // 1. A merge option was specified explicitly as the argument to Execute(MergeOption). // 2. The user has set the MergeOption property on the ObjectQuery instance. // 3. A merge option has been extracted from the 'root' query and propagated to the root of the expression tree. // 4. The global default merge option. MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, converter.PropagatedMergeOption); // If parameters were aggregated from referenced (non-LINQ) ObjectQuery instances then add them to the parameters collection if (converter.Parameters != null && converter.Parameters.Count > 0) { ObjectParameterCollection currentParams = this.EnsureParameters(); currentParams.SetReadOnly(false); foreach (ObjectParameter convertedParam in converter.Parameters) { // Note that it is safe to add the parameter directly only // because parameters are cloned before they are added to the // converter's parameter collection, or they came from this // instance's parameter collection in the first place. currentParams.Add(convertedParam); } currentParams.SetReadOnly(true); } plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan); this._cachedPlan = plan; } if (this.Parameters != null) { this.Parameters.SetReadOnly(true); } return plan; } ////// Returns a new ObjectQueryState instance with the specified navigation property path specified as an Include span. /// For eLINQ queries the Include operation is modelled as a method call expression applied to the source ObectQuery, /// so the ///property is always null on the returned instance. ///The element type of the resulting query /// The ObjectQuery on which Include was called; required to build the new method call expression /// The new Include path ///A new ObjectQueryState instance that incorporates the Include path, in this case a new method call expression internal override ObjectQueryState Include(ObjectQuery sourceQuery, string includePath) { MethodInfo includeMethod = sourceQuery.GetType().GetMethod("Include", BindingFlags.Public | BindingFlags.Instance); Debug.Assert(includeMethod != null, "Unable to find ObjectQuery.Include method?"); LinqExpression includeCall = LinqExpression.Call(LinqExpression.Constant(sourceQuery), includeMethod, new LinqExpression[] { LinqExpression.Constant(includePath, typeof(string)) }); ObjectQueryState retState = new ELinqQueryState(this.ElementType, this.ObjectContext, includeCall); this.ApplySettingsTo(retState); return retState; } /// /// eLINQ queries do not have command text. This method always returns /// Always set tofalse . ///null ///Always returns internal override bool TryGetCommandText(out string commandText) { commandText = null; return false; } ///false /// Gets the LINQ Expression that defines this query for external (of ObjectQueryState) use. /// Note that the /// The LINQ expression that describes this query ///property is used, which is overridden by compiled eLINQ /// queries to produce an Expression tree where parameter references have been replaced with constants. /// Always returns internal override bool TryGetExpression(out System.Linq.Expressions.Expression expression) { expression = this.Expression; return true; } #endregion internal virtual LinqExpression Expression { get { return _expression; } } protected virtual ExpressionConverter CreateExpressionConverter() { DbQueryCommandTree tree = new DbQueryCommandTree(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace); return new ExpressionConverter(this.ObjectContext, new BindingContext(), tree, _expression, null); } private void ResetParameters() { if (this.Parameters != null) { bool wasLocked = ((ICollectiontrue )this.Parameters).IsReadOnly; if (wasLocked) { this.Parameters.SetReadOnly(false); } this.Parameters.Clear(); if (wasLocked) { this.Parameters.SetReadOnly(true); } } } } } // 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
- XmlSchemaComplexType.cs
- ConfigXmlSignificantWhitespace.cs
- MimeXmlImporter.cs
- Tile.cs
- XPathSingletonIterator.cs
- SettingsPropertyValueCollection.cs
- WeakReadOnlyCollection.cs
- _NTAuthentication.cs
- DelimitedListTraceListener.cs
- XmlTextWriter.cs
- CaseKeyBox.xaml.cs
- CategoryValueConverter.cs
- XmlSchemaComplexContentRestriction.cs
- ReachSerializerAsync.cs
- Opcode.cs
- XmlSchemaSimpleContentRestriction.cs
- LateBoundBitmapDecoder.cs
- JournalEntry.cs
- PresentationTraceSources.cs
- DbBuffer.cs
- RelationshipFixer.cs
- EndpointDiscoveryBehavior.cs
- GridViewPageEventArgs.cs
- TextRangeEdit.cs
- ScrollBarRenderer.cs
- SystemIPInterfaceStatistics.cs
- ServiceHttpHandlerFactory.cs
- Grid.cs
- ScopedMessagePartSpecification.cs
- NativeMethods.cs
- ApplicationFileParser.cs
- TraceHwndHost.cs
- RuntimeResourceSet.cs
- StateDesigner.Helpers.cs
- ApplicationBuildProvider.cs
- ComponentChangedEvent.cs
- SerializationTrace.cs
- CrossContextChannel.cs
- ScriptManagerProxy.cs
- IsolatedStorageFile.cs
- StorageEntityContainerMapping.cs
- PatternMatcher.cs
- SafeProcessHandle.cs
- ProxyElement.cs
- AsnEncodedData.cs
- SqlConnectionString.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- ToolStripComboBox.cs
- BindingContext.cs
- NavigationFailedEventArgs.cs
- EndPoint.cs
- InvalidDataException.cs
- PropertyMapper.cs
- CompilerCollection.cs
- AspNetPartialTrustHelpers.cs
- DiagnosticTraceSource.cs
- DataGrid.cs
- XmlArrayItemAttribute.cs
- RegexReplacement.cs
- ImageCodecInfo.cs
- ChildDocumentBlock.cs
- RoleManagerModule.cs
- DbConnectionFactory.cs
- ReturnEventArgs.cs
- ElementUtil.cs
- CompModSwitches.cs
- OrderedDictionary.cs
- SharedPersonalizationStateInfo.cs
- SizeKeyFrameCollection.cs
- NamespaceQuery.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- WebConfigurationHost.cs
- DesignSurfaceCollection.cs
- TrailingSpaceComparer.cs
- WebAdminConfigurationHelper.cs
- SHA512CryptoServiceProvider.cs
- DecimalAnimation.cs
- ListViewAutomationPeer.cs
- Vars.cs
- LoginNameDesigner.cs
- HostingEnvironment.cs
- QilStrConcatenator.cs
- DiscoveryDocumentSerializer.cs
- XmlnsPrefixAttribute.cs
- StringOutput.cs
- ModelUtilities.cs
- SecurityContext.cs
- FormsAuthenticationUser.cs
- ScrollData.cs
- ExpressionNormalizer.cs
- LongAverageAggregationOperator.cs
- sitestring.cs
- PerformanceCounter.cs
- FormsAuthenticationConfiguration.cs
- cookiecollection.cs
- AuthenticationModeHelper.cs
- WebPartConnectionsEventArgs.cs
- TextTrailingWordEllipsis.cs
- HostProtectionException.cs
- JobInputBins.cs