Entity Framework - 11. ObjectQuery<T> (2)
[ 2009-04-01 11:36:47 | 作者: yuhen ]
2. Execute
不管是使用 LINQ foreach 方式,还是直接调用 Execute(),其执行流程都指向 GetResults()。
既然找到了线头,我们继续跟下去看看。
EntitySqlQueryState,很显然 ObjectQuery.PlanCachingEnabled 在 GetExecutionPlan() 中开始发挥作用。
ObjectQueryExecutionPlan 这个名字已经预示着我们即将看到一些更底层的东西。
DbProvidersServices, DbConnection, DbCommandDefinition …… 路不多了。在得到 ObjectQueryExecutionPlan 对象后,ObjectQuery<T>.GetResults() 调用其 Execute()。
EntityClient 要做的事情就已经很明了了,无需我们再说什么。
评论Feed: http://www.rainsts.net/feed.asp?q=comment&id=799
不管是使用 LINQ foreach 方式,还是直接调用 Execute(),其执行流程都指向 GetResults()。
public class ObjectQuery<T> : ObjectQuery, ...
{
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
IEnumerator<T> enumerator;
ObjectResult<T> results = this.GetResults(null);
try
{
enumerator = results.GetEnumerator();
}
catch
{
results.Dispose();
throw;
}
return enumerator;
}
public ObjectResult<T> Execute(MergeOption mergeOption)
{
EntityUtil.CheckArgumentMergeOption(mergeOption);
return this.GetResults(new MergeOption?(mergeOption));
}
}既然找到了线头,我们继续跟下去看看。
public class ObjectQuery<T> : ObjectQuery, ...
{
private ObjectResult<T> GetResults(MergeOption? forMergeOption)
{
ObjectResult<T> result;
base.QueryState.ObjectContext.EnsureConnection();
try
{
result = base.QueryState.GetExecutionPlan(forMergeOption).
Execute<T>(base.QueryState.ObjectContext, base.QueryState.Parameters);
}
catch
{
base.QueryState.ObjectContext.ReleaseConnection();
throw;
}
return result;
}
public ObjectQuery(string commandText, ObjectContext context, MergeOption mergeOption) :
this(new EntitySqlQueryState(typeof(T), ...))
{
...
}
}EntitySqlQueryState,很显然 ObjectQuery.PlanCachingEnabled 在 GetExecutionPlan() 中开始发挥作用。
internal sealed class EntitySqlQueryState : ObjectQueryState
{
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption)
{
...
if (base.PlanCachingEnabled)
{
...
if (queryCacheManager.TryCacheLookup(objectQueryCacheKey, out execPlan))
{
executionPlan = execPlan;
}
}
if (executionPlan == null)
{
DbQueryCommandTree tree;
tree = new DbQueryCommandTree(base.ObjectContext.MetadataWorkspace, DataSpace.CSpace)
{
Query = this.Parse(tree)
}
};
executionPlan = ObjectQueryExecutionPlan.Prepare(base.ObjectContext, tree, ...);
if (objectQueryCacheKey != null)
{
...
if (queryCacheManager.TryLookupAndAdd(inQueryCacheEntry, out outQueryCacheEntry))
{
executionPlan = ((EntitySqlQueryCacheEntry) outQueryCacheEntry).ExecutionPlan;
}
}
...
return executionPlan;
}
}ObjectQueryExecutionPlan 这个名字已经预示着我们即将看到一些更底层的东西。
internal sealed class ObjectQueryExecutionPlan
{
internal static ObjectQueryExecutionPlan Prepare(ObjectContext context, DbQueryCommandTree tree, ...)
{
...
DbConnection connection = context.Connection;
DbCommandDefinition commandDefinition = null;
...
DbProviderServices providerServices = DbProviderServices.GetProviderServices(connection);
...
commandDefinition = providerServices.CreateCommandDefinition(tree);
...
EntityCommandDefinition definition2 = (EntityCommandDefinition) commandDefinition;
QueryCacheManager queryCacheManager = context.Perspective.MetadataWorkspace.GetQueryCacheManager();
ShaperFactory resultShaperFactory = ShaperFactory.Create(elementType, queryCacheManager, ...);
...
return new ObjectQueryExecutionPlan(commandDefinition, resultShaperFactory, ...);
}
}DbProvidersServices, DbConnection, DbCommandDefinition …… 路不多了。在得到 ObjectQueryExecutionPlan 对象后,ObjectQuery<T>.GetResults() 调用其 Execute()。
internal sealed class ObjectQueryExecutionPlan
{
internal ObjectResult<TResultType> Execute<TResultType>(ObjectContext context, ...parameterValues)
{
DbDataReader reader = null;
ObjectResult<TResultType> result;
try
{
TypeUsage typeUsage;
EntityCommandDefinition commandDefinition = (EntityCommandDefinition) this.CommandDefinition;
EntityCommand entityCommand = new EntityCommand((EntityConnection) context.Connection, ...);
...
reader = commandDefinition.ExecuteStoreCommands(entityCommand, CommandBehavior.Default);
...
result = new ObjectResult<TResultType>(shaper, this._singleEntitySet, typeUsage);
}
catch (Exception)
{
...
}
return result;
}
}EntityClient 要做的事情就已经很明了了,无需我们再说什么。
[最后修改由 yuhen, 于 2009-04-01 11:37:54]
评论Feed: http://www.rainsts.net/feed.asp?q=comment&id=799
这篇日志没有评论。







