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 false .
///
/// Always set to null
/// Always returns false
internal override bool TryGetCommandText(out string commandText)
{
commandText = null;
return false;
}
///
/// Gets the LINQ Expression that defines this query for external (of ObjectQueryState) use.
/// Note that the property is used, which is overridden by compiled eLINQ
/// queries to produce an Expression tree where parameter references have been replaced with constants.
///
/// The LINQ expression that describes this query
/// Always returns true
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 = ((ICollection)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 false .
///
/// Always set to null
/// Always returns false
internal override bool TryGetCommandText(out string commandText)
{
commandText = null;
return false;
}
///
/// Gets the LINQ Expression that defines this query for external (of ObjectQueryState) use.
/// Note that the property is used, which is overridden by compiled eLINQ
/// queries to produce an Expression tree where parameter references have been replaced with constants.
///
/// The LINQ expression that describes this query
/// Always returns true
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 = ((ICollection)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
- RequestedSignatureDialog.cs
- DataControlFieldCell.cs
- PermissionToken.cs
- UserControlAutomationPeer.cs
- XmlBinaryReader.cs
- XmlWhitespace.cs
- BatchServiceHost.cs
- AppDomainAttributes.cs
- BaseCodeDomTreeGenerator.cs
- RoleManagerSection.cs
- EditorPartCollection.cs
- DateTimeUtil.cs
- EventToken.cs
- SqlCaseSimplifier.cs
- RangeValuePattern.cs
- ParallelEnumerable.cs
- CoTaskMemHandle.cs
- SHA1.cs
- OpacityConverter.cs
- ClientFormsAuthenticationCredentials.cs
- InstalledFontCollection.cs
- InputLanguageProfileNotifySink.cs
- AnnotationResourceChangedEventArgs.cs
- AttributeData.cs
- ReceiveContent.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- HtmlInputHidden.cs
- TableLayoutPanelDesigner.cs
- VScrollBar.cs
- XmlAnyAttributeAttribute.cs
- CodeSnippetCompileUnit.cs
- SystemNetworkInterface.cs
- CodeGotoStatement.cs
- XamlSerializerUtil.cs
- RowTypePropertyElement.cs
- SafeEventLogReadHandle.cs
- OperationAbortedException.cs
- ThreadPoolTaskScheduler.cs
- SafeNativeMethodsCLR.cs
- HwndTarget.cs
- CheckedPointers.cs
- CallContext.cs
- GeneralTransform3D.cs
- TextClipboardData.cs
- TextBoxBase.cs
- PerformanceCounter.cs
- DynamicMetaObject.cs
- printdlgexmarshaler.cs
- Rect3D.cs
- XmlSchemaAny.cs
- HttpRuntimeSection.cs
- PointLight.cs
- FixedSOMTable.cs
- Decimal.cs
- DataGridViewComboBoxEditingControl.cs
- ProxyAttribute.cs
- InheritanceAttribute.cs
- NamedPipeTransportSecurity.cs
- TargetConverter.cs
- ObjectManager.cs
- IgnoreFileBuildProvider.cs
- TemplateBindingExpression.cs
- MessageSecurityProtocolFactory.cs
- TraceLog.cs
- Grammar.cs
- TiffBitmapEncoder.cs
- Rfc2898DeriveBytes.cs
- HitTestWithPointDrawingContextWalker.cs
- Privilege.cs
- TableLayout.cs
- DrawItemEvent.cs
- CounterCreationDataConverter.cs
- XPathNodePointer.cs
- Brush.cs
- _FixedSizeReader.cs
- PageContentAsyncResult.cs
- BuilderPropertyEntry.cs
- DataGridViewImageCell.cs
- CalendarDataBindingHandler.cs
- TextTreeUndo.cs
- DBConnection.cs
- TraceSource.cs
- TypeForwardedToAttribute.cs
- DataGridParentRows.cs
- SystemIPv4InterfaceProperties.cs
- SafeNativeMethodsMilCoreApi.cs
- WmlSelectionListAdapter.cs
- HttpsTransportBindingElement.cs
- AccessViolationException.cs
- WebPermission.cs
- SimplePropertyEntry.cs
- WindowsToolbarItemAsMenuItem.cs
- AstNode.cs
- Membership.cs
- FrameworkContentElementAutomationPeer.cs
- ModelFactory.cs
- XpsFilter.cs
- SettingsAttributeDictionary.cs
- AnonymousIdentificationSection.cs
- UshortList2.cs