Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Objects / Internal / EntitySqlQueryState.cs / 1 / EntitySqlQueryState.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
//---------------------------------------------------------------------
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Common.CommandTrees;
using System.Data.Common.EntitySql;
using System.Data.Common.QueryCache;
using System.Data.Common.Utils;
using System.Data.EntityClient;
using System.Data.Metadata.Edm;
using System.Data.Objects.Internal;
using System.Diagnostics;
namespace System.Data.Objects
{
///
/// ObjectQueryState based on Entity-SQL query text.
///
internal sealed class EntitySqlQueryState : ObjectQueryState
{
///
/// The Entity-SQL text that defines the query.
///
private readonly string _queryText;
///
/// Can a Limit subclause be appended to the text of this query?
///
private readonly bool _allowsLimit;
///
/// Initializes a new query EntitySqlQueryState instance.
///
///
/// The ObjectContext containing the metadata workspace the query was
/// built against, the connection on which to execute the query, and the
/// cache to store the results in. Must not be null.
///
///
/// The Entity-SQL text of the query
///
///
/// The merge option to use when retrieving results if an explicit merge option is not specified
///
internal EntitySqlQueryState(Type elementType, string commandText, bool allowsLimit, ObjectContext context, ObjectParameterCollection parameters, Span span)
: base(elementType, context, parameters, span)
{
EntityUtil.CheckArgumentNull(commandText, "commandText");
if (string.IsNullOrEmpty(commandText))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.ObjectQuery_InvalidEmptyQuery, "commandText");
}
_queryText = commandText;
_allowsLimit = allowsLimit;
}
///
/// Determines whether or not the current query is a 'Skip' or 'Sort' operation
/// and so would allow a 'Limit' clause to be appended to the current query text.
///
///
/// True if the current query is a Skip or Sort expression, or a
/// Project expression with a Skip or Sort expression input.
///
internal bool AllowsLimitSubclause { get { return _allowsLimit; } }
///
/// Always returns the Entity-SQL text of the implemented ObjectQuery.
///
/// Always set to the Entity-SQL text of this ObjectQuery.
/// Always returns true .
internal override bool TryGetCommandText(out string commandText)
{
commandText = this._queryText;
return true;
}
internal override bool TryGetExpression(out System.Linq.Expressions.Expression expression)
{
expression = null;
return false;
}
protected override TypeUsage GetResultType()
{
DbQueryCommandTree tree = new DbQueryCommandTree(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace);
DbExpression query = this.Parse(tree);
return query.ResultType;
}
internal override ObjectQueryState Include(ObjectQuery sourceQuery, string includePath)
{
ObjectQueryState retState = new EntitySqlQueryState(this.ElementType, _queryText, _allowsLimit, this.ObjectContext, ObjectParameterCollection.DeepCopy(this.Parameters), Span.IncludeIn(this.Span, includePath));
this.ApplySettingsTo(retState);
return retState;
}
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption)
{
// Metadata is required to generate the execution plan or to retrieve it from the cache.
this.ObjectContext.EnsureMetadata();
// Determine the required merge option, with the following precedence:
// 1. The merge option specified to Execute(MergeOption) as forMergeOption.
// 2. The merge option set via ObjectQuery.MergeOption.
// 3. The global default merge option.
MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption);
// If a cached plan is present, then it can be reused if it has the required merge option
// (since span and parameters cannot change between executions). However, if the cached
// plan does not have the required merge option we proceed as if it were not present.
ObjectQueryExecutionPlan plan = this._cachedPlan;
if (plan != null)
{
if (plan.MergeOption == mergeOption)
{
return plan;
}
else
{
plan = null;
}
}
// There is no cached plan (or it was cleared), so the execution plan must be retrieved from
// the global query cache (if plan caching is enabled) or rebuilt for the required merge option.
QueryCacheManager cacheManager = null;
EntitySqlQueryCacheKey cacheKey = null;
if (this.PlanCachingEnabled)
{
// Create a new cache key that reflects the current state of the Parameters collection
// and the Span object (if any), and uses the specified merge option.
cacheKey = new EntitySqlQueryCacheKey(
this.ObjectContext.DefaultContainerName,
_queryText,
(null == this.Parameters ? 0 : this.Parameters.Count),
(null == this.Parameters ? null : this.Parameters.GetCacheKey()),
(null == this.Span ? null : this.Span.GetCacheKey()),
mergeOption,
this.ElementType);
cacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager();
ObjectQueryExecutionPlan executionPlan = null;
if (cacheManager.TryCacheLookup(cacheKey, out executionPlan))
{
plan = executionPlan;
}
}
if (plan == null)
{
// Either caching is not enabled or the execution plan was not found in the cache
DbQueryCommandTree tree = new DbQueryCommandTree(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace);
tree.Query = this.Parse(tree);
Debug.Assert(tree.Query != null, "EntitySqlQueryState.Parse returned null expression?");
plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, this.Span);
// If caching is enabled then update the cache now
if (cacheKey != null)
{
EntitySqlQueryCacheEntry newEntry = new EntitySqlQueryCacheEntry(cacheKey, plan);
QueryCacheEntry foundEntry = null;
if (cacheManager.TryLookupAndAdd(newEntry, out foundEntry))
{
// If TryLookupAndAdd returns 'true' then the entry was already present in the cache when the attempt to add was made.
// In this case the existing execution plan should be used.
plan = ((EntitySqlQueryCacheEntry)foundEntry).ExecutionPlan;
}
}
}
if (this.Parameters != null)
{
this.Parameters.SetReadOnly(true);
}
// Update the cached plan with the newly retrieved/prepared plan
this._cachedPlan = plan;
// Return the execution plan
return plan;
}
internal DbExpression Parse(DbCommandTree parseTree)
{
Dictionary paramTypes = null;
if (this.Parameters != null)
{
paramTypes = new Dictionary(this.Parameters.Count);
foreach (ObjectParameter parameter in this.Parameters)
{
TypeUsage typeUsage = parameter.TypeUsage;
if (null == typeUsage)
{
// Since ObjectParameters do not allow users to specify 'facets', make
// sure that the parameter TypeUsage is not populated with the provider
// default facet values.
this.ObjectContext.Perspective.TryGetTypeByName(
parameter.MappableType.FullName,
false /* bIgnoreCase */,
out typeUsage);
}
paramTypes.Add(parameter.Name, typeUsage);
}
}
DbExpression expr =
CqlQuery.Compile(
parseTree,
_queryText, // Command Text
this.ObjectContext.Perspective, // Perspective
null, // Parser options - null indicates 'use default'
paramTypes, // Parameters
null // Variables
);
return expr;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
//---------------------------------------------------------------------
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Common.CommandTrees;
using System.Data.Common.EntitySql;
using System.Data.Common.QueryCache;
using System.Data.Common.Utils;
using System.Data.EntityClient;
using System.Data.Metadata.Edm;
using System.Data.Objects.Internal;
using System.Diagnostics;
namespace System.Data.Objects
{
///
/// ObjectQueryState based on Entity-SQL query text.
///
internal sealed class EntitySqlQueryState : ObjectQueryState
{
///
/// The Entity-SQL text that defines the query.
///
private readonly string _queryText;
///
/// Can a Limit subclause be appended to the text of this query?
///
private readonly bool _allowsLimit;
///
/// Initializes a new query EntitySqlQueryState instance.
///
///
/// The ObjectContext containing the metadata workspace the query was
/// built against, the connection on which to execute the query, and the
/// cache to store the results in. Must not be null.
///
///
/// The Entity-SQL text of the query
///
///
/// The merge option to use when retrieving results if an explicit merge option is not specified
///
internal EntitySqlQueryState(Type elementType, string commandText, bool allowsLimit, ObjectContext context, ObjectParameterCollection parameters, Span span)
: base(elementType, context, parameters, span)
{
EntityUtil.CheckArgumentNull(commandText, "commandText");
if (string.IsNullOrEmpty(commandText))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.ObjectQuery_InvalidEmptyQuery, "commandText");
}
_queryText = commandText;
_allowsLimit = allowsLimit;
}
///
/// Determines whether or not the current query is a 'Skip' or 'Sort' operation
/// and so would allow a 'Limit' clause to be appended to the current query text.
///
///
/// True if the current query is a Skip or Sort expression, or a
/// Project expression with a Skip or Sort expression input.
///
internal bool AllowsLimitSubclause { get { return _allowsLimit; } }
///
/// Always returns the Entity-SQL text of the implemented ObjectQuery.
///
/// Always set to the Entity-SQL text of this ObjectQuery.
/// Always returns true .
internal override bool TryGetCommandText(out string commandText)
{
commandText = this._queryText;
return true;
}
internal override bool TryGetExpression(out System.Linq.Expressions.Expression expression)
{
expression = null;
return false;
}
protected override TypeUsage GetResultType()
{
DbQueryCommandTree tree = new DbQueryCommandTree(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace);
DbExpression query = this.Parse(tree);
return query.ResultType;
}
internal override ObjectQueryState Include(ObjectQuery sourceQuery, string includePath)
{
ObjectQueryState retState = new EntitySqlQueryState(this.ElementType, _queryText, _allowsLimit, this.ObjectContext, ObjectParameterCollection.DeepCopy(this.Parameters), Span.IncludeIn(this.Span, includePath));
this.ApplySettingsTo(retState);
return retState;
}
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption)
{
// Metadata is required to generate the execution plan or to retrieve it from the cache.
this.ObjectContext.EnsureMetadata();
// Determine the required merge option, with the following precedence:
// 1. The merge option specified to Execute(MergeOption) as forMergeOption.
// 2. The merge option set via ObjectQuery.MergeOption.
// 3. The global default merge option.
MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption);
// If a cached plan is present, then it can be reused if it has the required merge option
// (since span and parameters cannot change between executions). However, if the cached
// plan does not have the required merge option we proceed as if it were not present.
ObjectQueryExecutionPlan plan = this._cachedPlan;
if (plan != null)
{
if (plan.MergeOption == mergeOption)
{
return plan;
}
else
{
plan = null;
}
}
// There is no cached plan (or it was cleared), so the execution plan must be retrieved from
// the global query cache (if plan caching is enabled) or rebuilt for the required merge option.
QueryCacheManager cacheManager = null;
EntitySqlQueryCacheKey cacheKey = null;
if (this.PlanCachingEnabled)
{
// Create a new cache key that reflects the current state of the Parameters collection
// and the Span object (if any), and uses the specified merge option.
cacheKey = new EntitySqlQueryCacheKey(
this.ObjectContext.DefaultContainerName,
_queryText,
(null == this.Parameters ? 0 : this.Parameters.Count),
(null == this.Parameters ? null : this.Parameters.GetCacheKey()),
(null == this.Span ? null : this.Span.GetCacheKey()),
mergeOption,
this.ElementType);
cacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager();
ObjectQueryExecutionPlan executionPlan = null;
if (cacheManager.TryCacheLookup(cacheKey, out executionPlan))
{
plan = executionPlan;
}
}
if (plan == null)
{
// Either caching is not enabled or the execution plan was not found in the cache
DbQueryCommandTree tree = new DbQueryCommandTree(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace);
tree.Query = this.Parse(tree);
Debug.Assert(tree.Query != null, "EntitySqlQueryState.Parse returned null expression?");
plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, this.Span);
// If caching is enabled then update the cache now
if (cacheKey != null)
{
EntitySqlQueryCacheEntry newEntry = new EntitySqlQueryCacheEntry(cacheKey, plan);
QueryCacheEntry foundEntry = null;
if (cacheManager.TryLookupAndAdd(newEntry, out foundEntry))
{
// If TryLookupAndAdd returns 'true' then the entry was already present in the cache when the attempt to add was made.
// In this case the existing execution plan should be used.
plan = ((EntitySqlQueryCacheEntry)foundEntry).ExecutionPlan;
}
}
}
if (this.Parameters != null)
{
this.Parameters.SetReadOnly(true);
}
// Update the cached plan with the newly retrieved/prepared plan
this._cachedPlan = plan;
// Return the execution plan
return plan;
}
internal DbExpression Parse(DbCommandTree parseTree)
{
Dictionary paramTypes = null;
if (this.Parameters != null)
{
paramTypes = new Dictionary(this.Parameters.Count);
foreach (ObjectParameter parameter in this.Parameters)
{
TypeUsage typeUsage = parameter.TypeUsage;
if (null == typeUsage)
{
// Since ObjectParameters do not allow users to specify 'facets', make
// sure that the parameter TypeUsage is not populated with the provider
// default facet values.
this.ObjectContext.Perspective.TryGetTypeByName(
parameter.MappableType.FullName,
false /* bIgnoreCase */,
out typeUsage);
}
paramTypes.Add(parameter.Name, typeUsage);
}
}
DbExpression expr =
CqlQuery.Compile(
parseTree,
_queryText, // Command Text
this.ObjectContext.Perspective, // Perspective
null, // Parser options - null indicates 'use default'
paramTypes, // Parameters
null // Variables
);
return expr;
}
}
}
// 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
- DataPagerField.cs
- RectangleGeometry.cs
- AliasedSlot.cs
- Typography.cs
- ArrayTypeMismatchException.cs
- CompositeControl.cs
- Frame.cs
- SimpleHandlerBuildProvider.cs
- ArrayWithOffset.cs
- BufferBuilder.cs
- MaterialGroup.cs
- XamlStyleSerializer.cs
- StatusBarPanel.cs
- SourceSwitch.cs
- MexHttpsBindingCollectionElement.cs
- WebControlsSection.cs
- CategoryState.cs
- InfoCardBinaryReader.cs
- MethodCallTranslator.cs
- WeakReference.cs
- XmlTextReaderImplHelpers.cs
- BamlWriter.cs
- StrokeCollection2.cs
- ContentFileHelper.cs
- Set.cs
- ParallelTimeline.cs
- PropertyCollection.cs
- HtmlTableRow.cs
- PageCatalogPartDesigner.cs
- ServiceObjectContainer.cs
- HuffCodec.cs
- ObjectListCommandEventArgs.cs
- DataGridViewCellStyle.cs
- CatalogZone.cs
- DrawingAttributeSerializer.cs
- ReadOnlyCollectionBuilder.cs
- DockPanel.cs
- PeerApplicationLaunchInfo.cs
- LicenseException.cs
- SectionInformation.cs
- LockCookie.cs
- Span.cs
- XamlNamespaceHelper.cs
- DataServiceEntityAttribute.cs
- FixedSOMPageElement.cs
- SpotLight.cs
- LocalClientSecuritySettingsElement.cs
- Win32KeyboardDevice.cs
- FieldDescriptor.cs
- DependencyPropertyAttribute.cs
- UxThemeWrapper.cs
- ProgressChangedEventArgs.cs
- XmlSignatureProperties.cs
- ImportException.cs
- PublisherMembershipCondition.cs
- DesignTimeTemplateParser.cs
- ZipPackagePart.cs
- QilList.cs
- QueuePropertyVariants.cs
- FileVersion.cs
- JsonReader.cs
- InputReportEventArgs.cs
- TextAction.cs
- TreeViewImageIndexConverter.cs
- DataRelationCollection.cs
- ConvertEvent.cs
- OleDbEnumerator.cs
- CqlParserHelpers.cs
- SystemResourceKey.cs
- NotImplementedException.cs
- UIElementPropertyUndoUnit.cs
- ChannelServices.cs
- StringInfo.cs
- ListViewTableCell.cs
- CapabilitiesAssignment.cs
- XmlTextWriter.cs
- ProxyWebPart.cs
- ThreadAbortException.cs
- CanonicalFontFamilyReference.cs
- BindToObject.cs
- CircleHotSpot.cs
- GacUtil.cs
- Int32AnimationUsingKeyFrames.cs
- ConfigXmlElement.cs
- PagedDataSource.cs
- Typography.cs
- ImageFormat.cs
- MulticastOption.cs
- SafeHandle.cs
- ControlBuilder.cs
- IISMapPath.cs
- AsymmetricSignatureDeformatter.cs
- Span.cs
- PageRanges.cs
- AddInDeploymentState.cs
- MemberAssignmentAnalysis.cs
- AstTree.cs
- ToolStripSplitStackLayout.cs
- DelayLoadType.cs
- CryptoApi.cs