Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / Internal / ExpressionCopier.cs / 4 / ExpressionCopier.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....], [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Data.Common;
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees;
namespace System.Data.Common.CommandTrees.Internal
{
///
/// Clones an expression tree
///
internal class ExpressionCopier : DbExpressionVisitor
{
///
/// The MetadataMapper class is a helper class that logically translates
/// metadata constructs from one space to another. The objects that are translated
/// include
/// Types
/// Properties
/// Methods
/// Functions
/// Extents
/// EntitySets
/// The default implementation is to simply return the specified metadata instance
/// (an 'identity' mapping)
///
protected class MetadataMapper
{
internal static readonly MetadataMapper IdentityMapper = new MetadataMapper();
internal MetadataMapper() {}
internal virtual EdmType Map(EdmType s) { return s; }
internal virtual EntitySetBase Map(EntitySetBase e) { return e; }
internal virtual EntitySet Map(EntitySet e) { return e; }
internal virtual EdmFunction Map(EdmFunction f) { return f; }
internal virtual NavigationProperty Map(NavigationProperty p) { return p; }
internal virtual EdmProperty Map(EdmProperty p) { return p; }
internal virtual RelationshipEndMember Map(RelationshipEndMember m) { return m; }
internal virtual TypeUsage Map(TypeUsage t) { return t; }
#if METHOD_EXPRESSION
internal virtual MethodMetadata Map(MethodMetadata m) { return m; }
#endif
}
private class WorkspaceMapper : MetadataMapper
{
private MetadataWorkspace _metadata;
private Dictionary _transientTypes = new Dictionary();
internal WorkspaceMapper(MetadataWorkspace destinationWorkspace)
: base()
{
_metadata = destinationWorkspace;
}
#region MetadataMapper Overrides
internal override EdmType Map(EdmType type)
{
EdmType retType = null;
if (BuiltInTypeKind.RefType == type.BuiltInTypeKind)
{
RefType refType = (RefType)type;
retType = new RefType((EntityType)Map(refType.ElementType));
}
else if (BuiltInTypeKind.CollectionType == type.BuiltInTypeKind)
{
CollectionType collectionType = (CollectionType)type;
retType = new CollectionType(Map(collectionType.TypeUsage));
}
else if (BuiltInTypeKind.RowType == type.BuiltInTypeKind)
{
RowType rowType = (RowType)type;
List columns = new List();
foreach (EdmProperty p in rowType.Properties)
{
columns.Add(new EdmProperty(p.Name, Map(p.TypeUsage)));
}
RowType newRowType = new RowType(columns, rowType.InitializerMetadata);
retType = newRowType;
}
else
{
if (!_metadata.TryGetType(type.Name, type.NamespaceName, type.DataSpace, out retType) ||
null == retType)
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_TypeNotFound(TypeHelpers.GetFullName(type)));
}
}
return retType;
}
internal override EntitySetBase Map(EntitySetBase e)
{
EntityContainer container;
if (_metadata.TryGetEntityContainer(e.EntityContainer.Name, e.EntityContainer.DataSpace, out container))
{
EntitySetBase extent = null;
if (container.BaseEntitySets.TryGetValue(e.Name, false, out extent) &&
extent != null)
{
return extent;
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntitySetNotFound(e.EntityContainer.Name, e.Name));
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntityContainerNotFound(e.EntityContainer.Name));
}
internal override EntitySet Map(EntitySet e)
{
EntityContainer container;
if(_metadata.TryGetEntityContainer(e.EntityContainer.Name, e.EntityContainer.DataSpace, out container))
{
EntitySetBase set = null;
if (container.BaseEntitySets.TryGetValue(e.Name, false, out set))
{
EntitySet entitySet = set as EntitySet;
if (entitySet != null)
{
return entitySet;
}
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntitySetNotFound(e.EntityContainer.Name, e.Name));
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntityContainerNotFound(e.EntityContainer.Name));
}
internal override EdmFunction Map(EdmFunction f)
{
TypeUsage[] paramTypes = new TypeUsage[f.Parameters.Count];
int idx = 0;
foreach (FunctionParameter p in f.Parameters)
{
paramTypes[idx] = Map(p.TypeUsage);
idx++;
}
EdmFunction retFunc = null;
if( _metadata.TryGetFunction(f.Name, f.NamespaceName, paramTypes, false, f.DataSpace, out retFunc) &&
retFunc != null)
{
return retFunc;
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_FunctionNotFound(TypeHelpers.GetFullName(f)));
}
internal override NavigationProperty Map(NavigationProperty prop)
{
NavigationProperty retProp;
if (!TryMapMember(prop, out retProp))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_PropertyNotFound(prop.Name, TypeHelpers.GetFullName(prop.DeclaringType)));
}
return retProp;
}
internal override EdmProperty Map(EdmProperty prop)
{
EdmProperty retProp;
if (!TryMapMember(prop, out retProp))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_PropertyNotFound(prop.Name, TypeHelpers.GetFullName(prop.DeclaringType)));
}
return retProp;
}
internal override RelationshipEndMember Map(RelationshipEndMember end)
{
RelationshipEndMember retEnd;
if (!TryMapMember(end, out retEnd))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EndNotFound(end.Name, TypeHelpers.GetFullName(end.DeclaringType)));
}
return retEnd;
}
private bool TryMapMember(TMemberType prop, out TMemberType foundProp) where TMemberType : EdmMember
{
foundProp = null;
StructuralType mappedType = Map(prop.DeclaringType) as StructuralType;
if (mappedType != null)
{
EdmMember foundMember = null;
if (mappedType.Members.TryGetValue(prop.Name, false, out foundMember))
{
foundProp = foundMember as TMemberType;
}
}
return (foundProp != null);
}
#if METHOD_EXPRESSION
internal override MethodMetadata Map(MethodMetadata meth)
{
MethodMetadata retMethod = null;
List mappedParamTypes = new List();
foreach (IParameterMetadata methParam in meth.Parameters)
{
mappedParamTypes.Add(this.Map(methParam.Type));
}
TypeMetadata mappedType = this.Map(meth.DefiningType);
foreach (MemberMetadata member in mappedType.GetMemberByName(meth.Name))
{
// Ignore the member if:
// - It's not a method, OR
// - It's IsStatic property doesn't match, OR
// - It doesn't declare the right number of parameters.
MethodMetadata mappedMeth = member as MethodMetadata;
if( null == mappedMeth ||
mappedMeth.IsStatic != meth.IsStatic ||
mappedMeth.Parameters.Count != mappedParamTypes.Count)
{
continue;
}
// Assume that the method matches, which is correct for the case
// where the required method and this method both declare no parameters.
bool paramMatch = true;
for (int idx = 0; idx < mappedParamTypes.Count; idx++)
{
// If the type of any parameter to the method under consideration
// does not match the type of the corresponding parameter from the
// source method, then this cannot be the correct destination method.
if (!mappedParamTypes[idx].Equals(mappedMeth.Parameters[idx].Type))
{
paramMatch = false;
break;
}
}
// If any of the parameter types didn't match then move on.
if (!paramMatch)
{
continue;
}
// This is the required method.
retMethod = mappedMeth;
break;
}
if (null == retMethod)
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_MethodNotFound(meth.Name, mappedType.FullName));
}
return retMethod;
}
#endif
internal override TypeUsage Map(TypeUsage type)
{
//
// If the target metatadata workspace contains the same type instances, then the type does not
// need to be 'mapped' and the same TypeUsage instance may be returned. This can happen if the
// target workspace and the workspace of the source Command Tree are using the same ItemCollection.
//
EdmType retEdmType = Map(type.EdmType);
if (object.ReferenceEquals(retEdmType, type.EdmType))
{
return type;
}
//
// Retrieve the Facets from this type usage so that
// 1) They can be used to map the type if it is a primitive type
// 2) They can be applied to the new type usage that references the mapped type
//
Facet[] facets = new Facet[type.Facets.Count];
int idx = 0;
foreach (Facet f in type.Facets)
{
facets[idx] = f;
idx++;
}
return TypeUsage.Create(retEdmType, facets);
}
#endregion
}
private MetadataMapper _mapper;
private DbCommandTree _commandTree;
protected DbCommandTree CommandTree
{
get { return this._commandTree; }
}
protected ExpressionCopier(DbCommandTree commandTree, MetadataMapper mapper)
{
_commandTree = commandTree;
_mapper = mapper;
}
private static MetadataMapper GetMapper(MetadataWorkspace source, MetadataWorkspace destination)
{
ItemCollection mappingItemCollection = source.GetItemCollection(DataSpace.CSSpace);
ItemCollection destinationMappingItemCollection = destination.GetItemCollection(DataSpace.CSSpace);
if (!object.ReferenceEquals(mappingItemCollection, destinationMappingItemCollection))
{
EntityBid.Trace(" Using cross-workspace metadata mapper\n");
return new WorkspaceMapper(destination);
}
EntityBid.Trace(" Using identity metadata mapper\n");
return MetadataMapper.IdentityMapper;
}
internal static DbExpression Copy(DbCommandTree destination, DbExpression expression)
{
Debug.Assert(destination != null, "Destination Command Tree is null");
Debug.Assert(expression != null, "DbExpression is null");
using(new EntityBid.ScopeAuto(" destination=%d#", destination.ObjectId))
{
EntityBid.Trace(" expression=%d#, %d{cqt.DbExpressionKind}\n", DbExpression.GetObjectId(expression), DbExpression.GetExpressionKind(expression));
ExpressionCopier copier = new ExpressionCopier(destination, GetMapper(expression.CommandTree.MetadataWorkspace, destination.MetadataWorkspace));
return copier.VisitExpr(expression);
}
}
public List VisitList(IList exprList) where T: DbExpression
{
List retList = null;
if (exprList != null)
{
retList = new List();
for (int idx = 0; idx < exprList.Count; idx++)
{
retList.Add((T)this.VisitExpr(exprList[idx]));
}
}
return retList;
}
public List VisitExprList(IList exprList)
{
return VisitList(exprList);
}
public DbExpressionBinding VisitBinding(DbExpressionBinding b)
{
DbExpression newExpr = VisitExpr(b.Expression);
return this._commandTree.CreateExpressionBinding(newExpr, b.VariableName);
}
public DbGroupExpressionBinding VisitGroupExpressionBinding(DbGroupExpressionBinding gb)
{
DbExpression newExpr = VisitExpr(gb.Expression);
return this._commandTree.CreateGroupExpressionBinding(newExpr, gb.VariableName, gb.GroupVariableName);
}
public List VisitBindingList(IList bindingList)
{
List retList = null;
if (bindingList != null)
{
retList = new List();
for (int idx = 0; idx < bindingList.Count; idx++)
{
retList.Add(this.VisitBinding(bindingList[idx]));
}
}
return retList;
}
public List VisitSortOrder(IList sortOrder)
{
List skeys = new List();
for(int idx = 0; idx < sortOrder.Count; idx++)
{
DbSortClause s = sortOrder[idx];
DbExpression keyExpr = VisitExpr(s.Expression);
bool asc = s.Ascending;
if(!string.IsNullOrEmpty(s.Collation))
{
skeys.Add(_commandTree.CreateSortClause(keyExpr, asc, s.Collation));
}
else
{
skeys.Add(_commandTree.CreateSortClause(keyExpr, asc));
}
}
return skeys;
}
public virtual DbFunctionAggregate VisitFunctionAggregate(DbFunctionAggregate a)
{
if (a.Distinct)
{
return _commandTree.CreateDistinctFunctionAggregate(_mapper.Map(a.Function), VisitExpr(a.Arguments[0]));
}
else
{
return _commandTree.CreateFunctionAggregate(_mapper.Map(a.Function), VisitExpr(a.Arguments[0]));
}
}
#if ENABLE_NESTAGGREGATE
public virtual NestAggregate VisitNestAggregate(NestAggregate a)
{
return _commandTree.CreateNestAggregate(VisitExpr(a.Arguments[0]));
}
#endif
public DbAggregate VisitAggregate(DbAggregate a)
{
DbFunctionAggregate funcA = a as DbFunctionAggregate;
if (funcA != null)
{
return VisitFunctionAggregate(funcA);
}
#if ENABLE_NESTAGGREGATE
else if (a is NestAggregate)
{
return VisitNestAggregate(a as NestAggregate);
}
#endif
return null;
}
public DbExpression VisitExpr(DbExpression expr)
{
if (expr == null)
{
return null;
}
return expr.Accept(this);
}
#region DbExpressionVisitor Members
public override DbExpression Visit(DbExpression e)
{
throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_General_UnsupportedExpression(e.GetType().FullName));
}
public override DbExpression Visit(DbConstantExpression e)
{
return _commandTree.CreateConstantExpression(e.Value, _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbNullExpression e)
{
return _commandTree.CreateNullExpression(_mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbVariableReferenceExpression e)
{
return _commandTree.CreateVariableReferenceExpression(e.VariableName, _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbParameterReferenceExpression e)
{
return _commandTree.CreateParameterReferenceExpression(e.ParameterName);
}
public override DbExpression Visit(DbFunctionExpression e)
{
if (e.IsLambda)
{
List> formals = new List>();
for(int idx = 0; idx < e.Function.Parameters.Count; idx++)
{
FunctionParameter formal = e.Function.Parameters[idx];
formals.Add(new KeyValuePair(formal.Name, _mapper.Map(formal.TypeUsage)));
}
return _commandTree.CreateLambdaFunctionExpression(formals, VisitExpr(e.LambdaBody), VisitExprList(e.Arguments));
}
else
{
return _commandTree.CreateFunctionExpression(_mapper.Map(e.Function), VisitExprList(e.Arguments));
}
}
#if METHOD_EXPRESSION
public override Expression Visit(MethodExpression e)
{
if (e.Method.IsStatic)
{
return _commandTree.CreateStaticMethodExpression(_mapper.Map(e.Method), VisitExprList(e.Arguments));
}
else
{
return _commandTree.CreateInstanceMethodExpression(_mapper.Map(e.Method), VisitExpr(e.Instance), VisitExprList(e.Arguments));
}
}
#endif
public override DbExpression Visit(DbPropertyExpression e)
{
DbExpression instanceCopy = VisitExpr(e.Instance);
if (Helper.IsNavigationProperty(e.Property))
{
return _commandTree.CreatePropertyExpression(_mapper.Map((NavigationProperty)e.Property), instanceCopy);
}
else if (Helper.IsEdmProperty(e.Property))
{
return _commandTree.CreatePropertyExpression(_mapper.Map((EdmProperty)e.Property), instanceCopy);
}
else
{
Debug.Assert(e.Property is RelationshipEndMember, "Invalid DbPropertyExpression - Property is not EdmProperty, NavigationProperty or RelationshipEndMember");
return _commandTree.CreatePropertyExpression(_mapper.Map((RelationshipEndMember)e.Property), instanceCopy);
}
}
public override DbExpression Visit(DbComparisonExpression e)
{
DbExpression left = VisitExpr(e.Left);
DbExpression right = VisitExpr(e.Right);
switch (e.ExpressionKind)
{
case DbExpressionKind.Equals:
return _commandTree.CreateEqualsExpression(left, right);
case DbExpressionKind.NotEquals:
return _commandTree.CreateNotEqualsExpression(left, right);
case DbExpressionKind.LessThan:
return _commandTree.CreateLessThanExpression(left, right);
case DbExpressionKind.GreaterThan:
return _commandTree.CreateGreaterThanExpression(left, right);
case DbExpressionKind.LessThanOrEquals:
return _commandTree.CreateLessThanOrEqualsExpression(left, right);
case DbExpressionKind.GreaterThanOrEquals:
return _commandTree.CreateGreaterThanOrEqualsExpression(left, right);
default:
return null;
}
}
public override DbExpression Visit(DbLikeExpression e)
{
return this._commandTree.CreateLikeExpression(
VisitExpr(e.Argument),
VisitExpr(e.Pattern),
VisitExpr(e.Escape)
);
}
public override DbExpression Visit(DbLimitExpression e)
{
DbExpression argument = VisitExpr(e.Argument);
DbExpression limit = VisitExpr(e.Limit);
if (e.WithTies)
{
return _commandTree.CreateLimitWithTiesExpression(argument, limit);
}
else
{
return _commandTree.CreateLimitExpression(argument, limit);
}
}
public override DbExpression Visit(DbIsNullExpression e)
{
DbExpression operand = this.VisitExpr(e.Argument);
return this._commandTree.CreateIsNullExpression(operand);
}
public override DbExpression Visit(DbArithmeticExpression e)
{
List args = VisitExprList(e.Arguments);
switch(e.ExpressionKind)
{
case DbExpressionKind.Plus:
return _commandTree.CreatePlusExpression(args[0], args[1]);
case DbExpressionKind.Minus:
return _commandTree.CreateMinusExpression(args[0], args[1]);
case DbExpressionKind.Multiply:
return _commandTree.CreateMultiplyExpression(args[0], args[1]);
case DbExpressionKind.Divide:
return _commandTree.CreateDivideExpression(args[0], args[1]);
case DbExpressionKind.Modulo:
return _commandTree.CreateModuloExpression(args[0], args[1]);
case DbExpressionKind.UnaryMinus:
return _commandTree.CreateUnaryMinusExpression(args[0]);
default:
return null;
}
}
public override DbExpression Visit(DbAndExpression e)
{
return _commandTree.CreateAndExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbOrExpression e)
{
return _commandTree.CreateOrExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbNotExpression e)
{
return _commandTree.CreateNotExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbDistinctExpression e)
{
return _commandTree.CreateDistinctExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbElementExpression e)
{
DbExpression arg = VisitExpr(e.Argument);
if (e.IsSinglePropertyUnwrapped)
{
return _commandTree.CreateElementExpressionUnwrapSingleProperty(arg);
}
return _commandTree.CreateElementExpression(arg);
}
public override DbExpression Visit(DbIsEmptyExpression e)
{
return _commandTree.CreateIsEmptyExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbUnionAllExpression e)
{
return _commandTree.CreateUnionAllExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbIntersectExpression e)
{
return _commandTree.CreateIntersectExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbExceptExpression e)
{
return _commandTree.CreateExceptExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbTreatExpression e)
{
return _commandTree.CreateTreatExpression(VisitExpr(e.Argument), _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbCastExpression e)
{
return _commandTree.CreateCastExpression(VisitExpr(e.Argument), _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbIsOfExpression e)
{
if (DbExpressionKind.IsOfOnly == e.ExpressionKind)
{
return _commandTree.CreateIsOfOnlyExpression(VisitExpr(e.Argument), _mapper.Map(e.OfType));
}
else
{
return _commandTree.CreateIsOfExpression(VisitExpr(e.Argument), _mapper.Map(e.OfType));
}
}
public override DbExpression Visit(DbOfTypeExpression e)
{
DbExpression arg = VisitExpr(e.Argument);
TypeUsage ofType = _mapper.Map(e.OfType);
if (DbExpressionKind.OfTypeOnly == e.ExpressionKind)
{
return _commandTree.CreateOfTypeOnlyExpression(arg, ofType);
}
else
{
return _commandTree.CreateOfTypeExpression(arg, ofType);
}
}
public override DbExpression Visit(DbCaseExpression e)
{
return _commandTree.CreateCaseExpression(VisitExprList(e.When), VisitExprList(e.Then), VisitExpr(e.Else));
}
public override DbExpression Visit(DbNewInstanceExpression e)
{
TypeUsage resultType = _mapper.Map(e.ResultType);
List args = VisitExprList(e.Arguments);
if (resultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType &&
e.HasRelatedEntityReferences)
{
List relatedRefs = new List(e.RelatedEntityReferences.Count);
for(int idx = 0; idx < e.RelatedEntityReferences.Count; idx++)
{
DbRelatedEntityRef sourceRef = e.RelatedEntityReferences[idx];
RelationshipEndMember fromEnd = _mapper.Map(sourceRef.SourceEnd) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'source' relation end property using ExpressionCopier's metadata mapper");
RelationshipEndMember toEnd = _mapper.Map(sourceRef.TargetEnd) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'target' relation end property using ExpressionCopier's metadata mapper");
DbExpression targetRef = this.VisitExpr(sourceRef.TargetEntityReference);
relatedRefs.Add(_commandTree.CreateRelatedEntityRef(fromEnd, toEnd, targetRef));
}
return _commandTree.CreateNewEntityWithRelationshipsExpression((EntityType)resultType.EdmType, args, relatedRefs);
}
else
{
return _commandTree.CreateNewInstanceExpression(resultType, args);
}
}
public override DbExpression Visit(DbRefExpression e)
{
RefType refType = TypeHelpers.GetEdmType(e.ResultType);
EntityTypeBase targetType = refType.ElementType;
return _commandTree.CreateRefExpression(_mapper.Map(e.EntitySet), VisitExpr(e.Argument), (EntityType)_mapper.Map(targetType));
}
public override DbExpression Visit(DbRelationshipNavigationExpression e)
{
RelationshipEndMember fromEnd = _mapper.Map(e.NavigateFrom) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'from' relation end property using ExpressionCopier's metadata mapper");
RelationshipEndMember toEnd = _mapper.Map(e.NavigateTo) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'to' relation end property using ExpressionCopier's metadata mapper");
return _commandTree.CreateRelationshipNavigationExpression(fromEnd, toEnd, VisitExpr(e.NavigationSource));
}
public override DbExpression Visit(DbDerefExpression e)
{
return _commandTree.CreateDerefExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbRefKeyExpression e)
{
return _commandTree.CreateRefKeyExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbEntityRefExpression e)
{
return _commandTree.CreateEntityRefExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbScanExpression e)
{
return _commandTree.CreateScanExpression(_mapper.Map(e.Target));
}
public override DbExpression Visit(DbFilterExpression e)
{
return _commandTree.CreateFilterExpression(VisitBinding(e.Input), VisitExpr(e.Predicate));
}
public override DbExpression Visit(DbProjectExpression e)
{
return _commandTree.CreateProjectExpression(VisitBinding(e.Input), VisitExpr(e.Projection));
}
public override DbExpression Visit(DbCrossJoinExpression e)
{
return _commandTree.CreateCrossJoinExpression(VisitBindingList(e.Inputs));
}
public override DbExpression Visit(DbJoinExpression e)
{
return _commandTree.CreateJoinExpressionByKind(
e.ExpressionKind,
VisitExpr(e.JoinCondition),
VisitBinding(e.Left),
VisitBinding(e.Right)
);
}
public override DbExpression Visit(DbApplyExpression e)
{
return _commandTree.CreateApplyExpressionByKind
(
e.ExpressionKind,
VisitBinding(e.Input),
VisitBinding(e.Apply)
);
}
public override DbExpression Visit(DbGroupByExpression e)
{
List> keys = new List>();
List> aggs = new List>();
Debug.Assert(TypeSemantics.IsCollectionType(e.ResultType), "ExpressionCopier encountered DbGroupByExpression with non-collection result type");
CollectionType resultType = TypeHelpers.GetEdmType(_mapper.Map(e.ResultType));
Debug.Assert(TypeSemantics.IsRowType(resultType.TypeUsage), "ExpressionCopier encountered DbGroupByExpression with non-record result element type");
RowType resultElementType = TypeHelpers.GetEdmType(resultType.TypeUsage);
ReadOnlyMetadataCollection cols = resultElementType.Properties;
int iColPos = 0;
for(int idx = 0; idx < e.Keys.Count; idx++)
{
keys.Add(new KeyValuePair(cols[iColPos].Name, VisitExpr(e.Keys[idx])));
iColPos++;
}
for(int idx = 0; idx < e.Aggregates.Count; idx++)
{
aggs.Add(new KeyValuePair(cols[iColPos].Name, VisitAggregate(e.Aggregates[idx])));
iColPos++;
}
return _commandTree.CreateGroupByExpression
(
this.VisitGroupExpressionBinding(e.Input),
keys,
aggs
);
}
public override DbExpression Visit(DbSkipExpression e)
{
return _commandTree.CreateSkipExpression(VisitBinding(e.Input), VisitSortOrder(e.SortOrder), VisitExpr(e.Count));
}
public override DbExpression Visit(DbSortExpression e)
{
return _commandTree.CreateSortExpression(VisitBinding(e.Input), VisitSortOrder(e.SortOrder));
}
public override DbExpression Visit(DbQuantifierExpression e)
{
DbExpressionBinding eb = VisitBinding(e.Input);
DbExpression pred = VisitExpr(e.Predicate);
if (e.ExpressionKind == DbExpressionKind.Any)
{
return _commandTree.CreateAnyExpression(eb, pred);
}
else
{
return _commandTree.CreateAllExpression(eb, pred);
}
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....], [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Data.Common;
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees;
namespace System.Data.Common.CommandTrees.Internal
{
///
/// Clones an expression tree
///
internal class ExpressionCopier : DbExpressionVisitor
{
///
/// The MetadataMapper class is a helper class that logically translates
/// metadata constructs from one space to another. The objects that are translated
/// include
/// Types
/// Properties
/// Methods
/// Functions
/// Extents
/// EntitySets
/// The default implementation is to simply return the specified metadata instance
/// (an 'identity' mapping)
///
protected class MetadataMapper
{
internal static readonly MetadataMapper IdentityMapper = new MetadataMapper();
internal MetadataMapper() {}
internal virtual EdmType Map(EdmType s) { return s; }
internal virtual EntitySetBase Map(EntitySetBase e) { return e; }
internal virtual EntitySet Map(EntitySet e) { return e; }
internal virtual EdmFunction Map(EdmFunction f) { return f; }
internal virtual NavigationProperty Map(NavigationProperty p) { return p; }
internal virtual EdmProperty Map(EdmProperty p) { return p; }
internal virtual RelationshipEndMember Map(RelationshipEndMember m) { return m; }
internal virtual TypeUsage Map(TypeUsage t) { return t; }
#if METHOD_EXPRESSION
internal virtual MethodMetadata Map(MethodMetadata m) { return m; }
#endif
}
private class WorkspaceMapper : MetadataMapper
{
private MetadataWorkspace _metadata;
private Dictionary _transientTypes = new Dictionary();
internal WorkspaceMapper(MetadataWorkspace destinationWorkspace)
: base()
{
_metadata = destinationWorkspace;
}
#region MetadataMapper Overrides
internal override EdmType Map(EdmType type)
{
EdmType retType = null;
if (BuiltInTypeKind.RefType == type.BuiltInTypeKind)
{
RefType refType = (RefType)type;
retType = new RefType((EntityType)Map(refType.ElementType));
}
else if (BuiltInTypeKind.CollectionType == type.BuiltInTypeKind)
{
CollectionType collectionType = (CollectionType)type;
retType = new CollectionType(Map(collectionType.TypeUsage));
}
else if (BuiltInTypeKind.RowType == type.BuiltInTypeKind)
{
RowType rowType = (RowType)type;
List columns = new List();
foreach (EdmProperty p in rowType.Properties)
{
columns.Add(new EdmProperty(p.Name, Map(p.TypeUsage)));
}
RowType newRowType = new RowType(columns, rowType.InitializerMetadata);
retType = newRowType;
}
else
{
if (!_metadata.TryGetType(type.Name, type.NamespaceName, type.DataSpace, out retType) ||
null == retType)
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_TypeNotFound(TypeHelpers.GetFullName(type)));
}
}
return retType;
}
internal override EntitySetBase Map(EntitySetBase e)
{
EntityContainer container;
if (_metadata.TryGetEntityContainer(e.EntityContainer.Name, e.EntityContainer.DataSpace, out container))
{
EntitySetBase extent = null;
if (container.BaseEntitySets.TryGetValue(e.Name, false, out extent) &&
extent != null)
{
return extent;
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntitySetNotFound(e.EntityContainer.Name, e.Name));
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntityContainerNotFound(e.EntityContainer.Name));
}
internal override EntitySet Map(EntitySet e)
{
EntityContainer container;
if(_metadata.TryGetEntityContainer(e.EntityContainer.Name, e.EntityContainer.DataSpace, out container))
{
EntitySetBase set = null;
if (container.BaseEntitySets.TryGetValue(e.Name, false, out set))
{
EntitySet entitySet = set as EntitySet;
if (entitySet != null)
{
return entitySet;
}
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntitySetNotFound(e.EntityContainer.Name, e.Name));
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EntityContainerNotFound(e.EntityContainer.Name));
}
internal override EdmFunction Map(EdmFunction f)
{
TypeUsage[] paramTypes = new TypeUsage[f.Parameters.Count];
int idx = 0;
foreach (FunctionParameter p in f.Parameters)
{
paramTypes[idx] = Map(p.TypeUsage);
idx++;
}
EdmFunction retFunc = null;
if( _metadata.TryGetFunction(f.Name, f.NamespaceName, paramTypes, false, f.DataSpace, out retFunc) &&
retFunc != null)
{
return retFunc;
}
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_FunctionNotFound(TypeHelpers.GetFullName(f)));
}
internal override NavigationProperty Map(NavigationProperty prop)
{
NavigationProperty retProp;
if (!TryMapMember(prop, out retProp))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_PropertyNotFound(prop.Name, TypeHelpers.GetFullName(prop.DeclaringType)));
}
return retProp;
}
internal override EdmProperty Map(EdmProperty prop)
{
EdmProperty retProp;
if (!TryMapMember(prop, out retProp))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_PropertyNotFound(prop.Name, TypeHelpers.GetFullName(prop.DeclaringType)));
}
return retProp;
}
internal override RelationshipEndMember Map(RelationshipEndMember end)
{
RelationshipEndMember retEnd;
if (!TryMapMember(end, out retEnd))
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_EndNotFound(end.Name, TypeHelpers.GetFullName(end.DeclaringType)));
}
return retEnd;
}
private bool TryMapMember(TMemberType prop, out TMemberType foundProp) where TMemberType : EdmMember
{
foundProp = null;
StructuralType mappedType = Map(prop.DeclaringType) as StructuralType;
if (mappedType != null)
{
EdmMember foundMember = null;
if (mappedType.Members.TryGetValue(prop.Name, false, out foundMember))
{
foundProp = foundMember as TMemberType;
}
}
return (foundProp != null);
}
#if METHOD_EXPRESSION
internal override MethodMetadata Map(MethodMetadata meth)
{
MethodMetadata retMethod = null;
List mappedParamTypes = new List();
foreach (IParameterMetadata methParam in meth.Parameters)
{
mappedParamTypes.Add(this.Map(methParam.Type));
}
TypeMetadata mappedType = this.Map(meth.DefiningType);
foreach (MemberMetadata member in mappedType.GetMemberByName(meth.Name))
{
// Ignore the member if:
// - It's not a method, OR
// - It's IsStatic property doesn't match, OR
// - It doesn't declare the right number of parameters.
MethodMetadata mappedMeth = member as MethodMetadata;
if( null == mappedMeth ||
mappedMeth.IsStatic != meth.IsStatic ||
mappedMeth.Parameters.Count != mappedParamTypes.Count)
{
continue;
}
// Assume that the method matches, which is correct for the case
// where the required method and this method both declare no parameters.
bool paramMatch = true;
for (int idx = 0; idx < mappedParamTypes.Count; idx++)
{
// If the type of any parameter to the method under consideration
// does not match the type of the corresponding parameter from the
// source method, then this cannot be the correct destination method.
if (!mappedParamTypes[idx].Equals(mappedMeth.Parameters[idx].Type))
{
paramMatch = false;
break;
}
}
// If any of the parameter types didn't match then move on.
if (!paramMatch)
{
continue;
}
// This is the required method.
retMethod = mappedMeth;
break;
}
if (null == retMethod)
{
throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Copier_MethodNotFound(meth.Name, mappedType.FullName));
}
return retMethod;
}
#endif
internal override TypeUsage Map(TypeUsage type)
{
//
// If the target metatadata workspace contains the same type instances, then the type does not
// need to be 'mapped' and the same TypeUsage instance may be returned. This can happen if the
// target workspace and the workspace of the source Command Tree are using the same ItemCollection.
//
EdmType retEdmType = Map(type.EdmType);
if (object.ReferenceEquals(retEdmType, type.EdmType))
{
return type;
}
//
// Retrieve the Facets from this type usage so that
// 1) They can be used to map the type if it is a primitive type
// 2) They can be applied to the new type usage that references the mapped type
//
Facet[] facets = new Facet[type.Facets.Count];
int idx = 0;
foreach (Facet f in type.Facets)
{
facets[idx] = f;
idx++;
}
return TypeUsage.Create(retEdmType, facets);
}
#endregion
}
private MetadataMapper _mapper;
private DbCommandTree _commandTree;
protected DbCommandTree CommandTree
{
get { return this._commandTree; }
}
protected ExpressionCopier(DbCommandTree commandTree, MetadataMapper mapper)
{
_commandTree = commandTree;
_mapper = mapper;
}
private static MetadataMapper GetMapper(MetadataWorkspace source, MetadataWorkspace destination)
{
ItemCollection mappingItemCollection = source.GetItemCollection(DataSpace.CSSpace);
ItemCollection destinationMappingItemCollection = destination.GetItemCollection(DataSpace.CSSpace);
if (!object.ReferenceEquals(mappingItemCollection, destinationMappingItemCollection))
{
EntityBid.Trace(" Using cross-workspace metadata mapper\n");
return new WorkspaceMapper(destination);
}
EntityBid.Trace(" Using identity metadata mapper\n");
return MetadataMapper.IdentityMapper;
}
internal static DbExpression Copy(DbCommandTree destination, DbExpression expression)
{
Debug.Assert(destination != null, "Destination Command Tree is null");
Debug.Assert(expression != null, "DbExpression is null");
using(new EntityBid.ScopeAuto(" destination=%d#", destination.ObjectId))
{
EntityBid.Trace(" expression=%d#, %d{cqt.DbExpressionKind}\n", DbExpression.GetObjectId(expression), DbExpression.GetExpressionKind(expression));
ExpressionCopier copier = new ExpressionCopier(destination, GetMapper(expression.CommandTree.MetadataWorkspace, destination.MetadataWorkspace));
return copier.VisitExpr(expression);
}
}
public List VisitList(IList exprList) where T: DbExpression
{
List retList = null;
if (exprList != null)
{
retList = new List();
for (int idx = 0; idx < exprList.Count; idx++)
{
retList.Add((T)this.VisitExpr(exprList[idx]));
}
}
return retList;
}
public List VisitExprList(IList exprList)
{
return VisitList(exprList);
}
public DbExpressionBinding VisitBinding(DbExpressionBinding b)
{
DbExpression newExpr = VisitExpr(b.Expression);
return this._commandTree.CreateExpressionBinding(newExpr, b.VariableName);
}
public DbGroupExpressionBinding VisitGroupExpressionBinding(DbGroupExpressionBinding gb)
{
DbExpression newExpr = VisitExpr(gb.Expression);
return this._commandTree.CreateGroupExpressionBinding(newExpr, gb.VariableName, gb.GroupVariableName);
}
public List VisitBindingList(IList bindingList)
{
List retList = null;
if (bindingList != null)
{
retList = new List();
for (int idx = 0; idx < bindingList.Count; idx++)
{
retList.Add(this.VisitBinding(bindingList[idx]));
}
}
return retList;
}
public List VisitSortOrder(IList sortOrder)
{
List skeys = new List();
for(int idx = 0; idx < sortOrder.Count; idx++)
{
DbSortClause s = sortOrder[idx];
DbExpression keyExpr = VisitExpr(s.Expression);
bool asc = s.Ascending;
if(!string.IsNullOrEmpty(s.Collation))
{
skeys.Add(_commandTree.CreateSortClause(keyExpr, asc, s.Collation));
}
else
{
skeys.Add(_commandTree.CreateSortClause(keyExpr, asc));
}
}
return skeys;
}
public virtual DbFunctionAggregate VisitFunctionAggregate(DbFunctionAggregate a)
{
if (a.Distinct)
{
return _commandTree.CreateDistinctFunctionAggregate(_mapper.Map(a.Function), VisitExpr(a.Arguments[0]));
}
else
{
return _commandTree.CreateFunctionAggregate(_mapper.Map(a.Function), VisitExpr(a.Arguments[0]));
}
}
#if ENABLE_NESTAGGREGATE
public virtual NestAggregate VisitNestAggregate(NestAggregate a)
{
return _commandTree.CreateNestAggregate(VisitExpr(a.Arguments[0]));
}
#endif
public DbAggregate VisitAggregate(DbAggregate a)
{
DbFunctionAggregate funcA = a as DbFunctionAggregate;
if (funcA != null)
{
return VisitFunctionAggregate(funcA);
}
#if ENABLE_NESTAGGREGATE
else if (a is NestAggregate)
{
return VisitNestAggregate(a as NestAggregate);
}
#endif
return null;
}
public DbExpression VisitExpr(DbExpression expr)
{
if (expr == null)
{
return null;
}
return expr.Accept(this);
}
#region DbExpressionVisitor Members
public override DbExpression Visit(DbExpression e)
{
throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_General_UnsupportedExpression(e.GetType().FullName));
}
public override DbExpression Visit(DbConstantExpression e)
{
return _commandTree.CreateConstantExpression(e.Value, _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbNullExpression e)
{
return _commandTree.CreateNullExpression(_mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbVariableReferenceExpression e)
{
return _commandTree.CreateVariableReferenceExpression(e.VariableName, _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbParameterReferenceExpression e)
{
return _commandTree.CreateParameterReferenceExpression(e.ParameterName);
}
public override DbExpression Visit(DbFunctionExpression e)
{
if (e.IsLambda)
{
List> formals = new List>();
for(int idx = 0; idx < e.Function.Parameters.Count; idx++)
{
FunctionParameter formal = e.Function.Parameters[idx];
formals.Add(new KeyValuePair(formal.Name, _mapper.Map(formal.TypeUsage)));
}
return _commandTree.CreateLambdaFunctionExpression(formals, VisitExpr(e.LambdaBody), VisitExprList(e.Arguments));
}
else
{
return _commandTree.CreateFunctionExpression(_mapper.Map(e.Function), VisitExprList(e.Arguments));
}
}
#if METHOD_EXPRESSION
public override Expression Visit(MethodExpression e)
{
if (e.Method.IsStatic)
{
return _commandTree.CreateStaticMethodExpression(_mapper.Map(e.Method), VisitExprList(e.Arguments));
}
else
{
return _commandTree.CreateInstanceMethodExpression(_mapper.Map(e.Method), VisitExpr(e.Instance), VisitExprList(e.Arguments));
}
}
#endif
public override DbExpression Visit(DbPropertyExpression e)
{
DbExpression instanceCopy = VisitExpr(e.Instance);
if (Helper.IsNavigationProperty(e.Property))
{
return _commandTree.CreatePropertyExpression(_mapper.Map((NavigationProperty)e.Property), instanceCopy);
}
else if (Helper.IsEdmProperty(e.Property))
{
return _commandTree.CreatePropertyExpression(_mapper.Map((EdmProperty)e.Property), instanceCopy);
}
else
{
Debug.Assert(e.Property is RelationshipEndMember, "Invalid DbPropertyExpression - Property is not EdmProperty, NavigationProperty or RelationshipEndMember");
return _commandTree.CreatePropertyExpression(_mapper.Map((RelationshipEndMember)e.Property), instanceCopy);
}
}
public override DbExpression Visit(DbComparisonExpression e)
{
DbExpression left = VisitExpr(e.Left);
DbExpression right = VisitExpr(e.Right);
switch (e.ExpressionKind)
{
case DbExpressionKind.Equals:
return _commandTree.CreateEqualsExpression(left, right);
case DbExpressionKind.NotEquals:
return _commandTree.CreateNotEqualsExpression(left, right);
case DbExpressionKind.LessThan:
return _commandTree.CreateLessThanExpression(left, right);
case DbExpressionKind.GreaterThan:
return _commandTree.CreateGreaterThanExpression(left, right);
case DbExpressionKind.LessThanOrEquals:
return _commandTree.CreateLessThanOrEqualsExpression(left, right);
case DbExpressionKind.GreaterThanOrEquals:
return _commandTree.CreateGreaterThanOrEqualsExpression(left, right);
default:
return null;
}
}
public override DbExpression Visit(DbLikeExpression e)
{
return this._commandTree.CreateLikeExpression(
VisitExpr(e.Argument),
VisitExpr(e.Pattern),
VisitExpr(e.Escape)
);
}
public override DbExpression Visit(DbLimitExpression e)
{
DbExpression argument = VisitExpr(e.Argument);
DbExpression limit = VisitExpr(e.Limit);
if (e.WithTies)
{
return _commandTree.CreateLimitWithTiesExpression(argument, limit);
}
else
{
return _commandTree.CreateLimitExpression(argument, limit);
}
}
public override DbExpression Visit(DbIsNullExpression e)
{
DbExpression operand = this.VisitExpr(e.Argument);
return this._commandTree.CreateIsNullExpression(operand);
}
public override DbExpression Visit(DbArithmeticExpression e)
{
List args = VisitExprList(e.Arguments);
switch(e.ExpressionKind)
{
case DbExpressionKind.Plus:
return _commandTree.CreatePlusExpression(args[0], args[1]);
case DbExpressionKind.Minus:
return _commandTree.CreateMinusExpression(args[0], args[1]);
case DbExpressionKind.Multiply:
return _commandTree.CreateMultiplyExpression(args[0], args[1]);
case DbExpressionKind.Divide:
return _commandTree.CreateDivideExpression(args[0], args[1]);
case DbExpressionKind.Modulo:
return _commandTree.CreateModuloExpression(args[0], args[1]);
case DbExpressionKind.UnaryMinus:
return _commandTree.CreateUnaryMinusExpression(args[0]);
default:
return null;
}
}
public override DbExpression Visit(DbAndExpression e)
{
return _commandTree.CreateAndExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbOrExpression e)
{
return _commandTree.CreateOrExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbNotExpression e)
{
return _commandTree.CreateNotExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbDistinctExpression e)
{
return _commandTree.CreateDistinctExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbElementExpression e)
{
DbExpression arg = VisitExpr(e.Argument);
if (e.IsSinglePropertyUnwrapped)
{
return _commandTree.CreateElementExpressionUnwrapSingleProperty(arg);
}
return _commandTree.CreateElementExpression(arg);
}
public override DbExpression Visit(DbIsEmptyExpression e)
{
return _commandTree.CreateIsEmptyExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbUnionAllExpression e)
{
return _commandTree.CreateUnionAllExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbIntersectExpression e)
{
return _commandTree.CreateIntersectExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbExceptExpression e)
{
return _commandTree.CreateExceptExpression(VisitExpr(e.Left), VisitExpr(e.Right));
}
public override DbExpression Visit(DbTreatExpression e)
{
return _commandTree.CreateTreatExpression(VisitExpr(e.Argument), _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbCastExpression e)
{
return _commandTree.CreateCastExpression(VisitExpr(e.Argument), _mapper.Map(e.ResultType));
}
public override DbExpression Visit(DbIsOfExpression e)
{
if (DbExpressionKind.IsOfOnly == e.ExpressionKind)
{
return _commandTree.CreateIsOfOnlyExpression(VisitExpr(e.Argument), _mapper.Map(e.OfType));
}
else
{
return _commandTree.CreateIsOfExpression(VisitExpr(e.Argument), _mapper.Map(e.OfType));
}
}
public override DbExpression Visit(DbOfTypeExpression e)
{
DbExpression arg = VisitExpr(e.Argument);
TypeUsage ofType = _mapper.Map(e.OfType);
if (DbExpressionKind.OfTypeOnly == e.ExpressionKind)
{
return _commandTree.CreateOfTypeOnlyExpression(arg, ofType);
}
else
{
return _commandTree.CreateOfTypeExpression(arg, ofType);
}
}
public override DbExpression Visit(DbCaseExpression e)
{
return _commandTree.CreateCaseExpression(VisitExprList(e.When), VisitExprList(e.Then), VisitExpr(e.Else));
}
public override DbExpression Visit(DbNewInstanceExpression e)
{
TypeUsage resultType = _mapper.Map(e.ResultType);
List args = VisitExprList(e.Arguments);
if (resultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType &&
e.HasRelatedEntityReferences)
{
List relatedRefs = new List(e.RelatedEntityReferences.Count);
for(int idx = 0; idx < e.RelatedEntityReferences.Count; idx++)
{
DbRelatedEntityRef sourceRef = e.RelatedEntityReferences[idx];
RelationshipEndMember fromEnd = _mapper.Map(sourceRef.SourceEnd) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'source' relation end property using ExpressionCopier's metadata mapper");
RelationshipEndMember toEnd = _mapper.Map(sourceRef.TargetEnd) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'target' relation end property using ExpressionCopier's metadata mapper");
DbExpression targetRef = this.VisitExpr(sourceRef.TargetEntityReference);
relatedRefs.Add(_commandTree.CreateRelatedEntityRef(fromEnd, toEnd, targetRef));
}
return _commandTree.CreateNewEntityWithRelationshipsExpression((EntityType)resultType.EdmType, args, relatedRefs);
}
else
{
return _commandTree.CreateNewInstanceExpression(resultType, args);
}
}
public override DbExpression Visit(DbRefExpression e)
{
RefType refType = TypeHelpers.GetEdmType(e.ResultType);
EntityTypeBase targetType = refType.ElementType;
return _commandTree.CreateRefExpression(_mapper.Map(e.EntitySet), VisitExpr(e.Argument), (EntityType)_mapper.Map(targetType));
}
public override DbExpression Visit(DbRelationshipNavigationExpression e)
{
RelationshipEndMember fromEnd = _mapper.Map(e.NavigateFrom) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'from' relation end property using ExpressionCopier's metadata mapper");
RelationshipEndMember toEnd = _mapper.Map(e.NavigateTo) as RelationshipEndMember;
Debug.Assert(fromEnd != null, "Unable to map 'to' relation end property using ExpressionCopier's metadata mapper");
return _commandTree.CreateRelationshipNavigationExpression(fromEnd, toEnd, VisitExpr(e.NavigationSource));
}
public override DbExpression Visit(DbDerefExpression e)
{
return _commandTree.CreateDerefExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbRefKeyExpression e)
{
return _commandTree.CreateRefKeyExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbEntityRefExpression e)
{
return _commandTree.CreateEntityRefExpression(VisitExpr(e.Argument));
}
public override DbExpression Visit(DbScanExpression e)
{
return _commandTree.CreateScanExpression(_mapper.Map(e.Target));
}
public override DbExpression Visit(DbFilterExpression e)
{
return _commandTree.CreateFilterExpression(VisitBinding(e.Input), VisitExpr(e.Predicate));
}
public override DbExpression Visit(DbProjectExpression e)
{
return _commandTree.CreateProjectExpression(VisitBinding(e.Input), VisitExpr(e.Projection));
}
public override DbExpression Visit(DbCrossJoinExpression e)
{
return _commandTree.CreateCrossJoinExpression(VisitBindingList(e.Inputs));
}
public override DbExpression Visit(DbJoinExpression e)
{
return _commandTree.CreateJoinExpressionByKind(
e.ExpressionKind,
VisitExpr(e.JoinCondition),
VisitBinding(e.Left),
VisitBinding(e.Right)
);
}
public override DbExpression Visit(DbApplyExpression e)
{
return _commandTree.CreateApplyExpressionByKind
(
e.ExpressionKind,
VisitBinding(e.Input),
VisitBinding(e.Apply)
);
}
public override DbExpression Visit(DbGroupByExpression e)
{
List> keys = new List>();
List> aggs = new List>();
Debug.Assert(TypeSemantics.IsCollectionType(e.ResultType), "ExpressionCopier encountered DbGroupByExpression with non-collection result type");
CollectionType resultType = TypeHelpers.GetEdmType(_mapper.Map(e.ResultType));
Debug.Assert(TypeSemantics.IsRowType(resultType.TypeUsage), "ExpressionCopier encountered DbGroupByExpression with non-record result element type");
RowType resultElementType = TypeHelpers.GetEdmType(resultType.TypeUsage);
ReadOnlyMetadataCollection cols = resultElementType.Properties;
int iColPos = 0;
for(int idx = 0; idx < e.Keys.Count; idx++)
{
keys.Add(new KeyValuePair(cols[iColPos].Name, VisitExpr(e.Keys[idx])));
iColPos++;
}
for(int idx = 0; idx < e.Aggregates.Count; idx++)
{
aggs.Add(new KeyValuePair(cols[iColPos].Name, VisitAggregate(e.Aggregates[idx])));
iColPos++;
}
return _commandTree.CreateGroupByExpression
(
this.VisitGroupExpressionBinding(e.Input),
keys,
aggs
);
}
public override DbExpression Visit(DbSkipExpression e)
{
return _commandTree.CreateSkipExpression(VisitBinding(e.Input), VisitSortOrder(e.SortOrder), VisitExpr(e.Count));
}
public override DbExpression Visit(DbSortExpression e)
{
return _commandTree.CreateSortExpression(VisitBinding(e.Input), VisitSortOrder(e.SortOrder));
}
public override DbExpression Visit(DbQuantifierExpression e)
{
DbExpressionBinding eb = VisitBinding(e.Input);
DbExpression pred = VisitExpr(e.Predicate);
if (e.ExpressionKind == DbExpressionKind.Any)
{
return _commandTree.CreateAnyExpression(eb, pred);
}
else
{
return _commandTree.CreateAllExpression(eb, pred);
}
}
#endregion
}
}
// 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
- ArrayList.cs
- DesignerCalendarAdapter.cs
- MetadataUtil.cs
- AsyncCompletedEventArgs.cs
- DeferredSelectedIndexReference.cs
- XmlAttributeAttribute.cs
- XmlAttributeCache.cs
- DataGridViewTextBoxColumn.cs
- TypeSource.cs
- ListControlStringCollectionEditor.cs
- CompiledELinqQueryState.cs
- SqlError.cs
- ClrPerspective.cs
- RadioButton.cs
- WorkflowApplicationEventArgs.cs
- MultiBinding.cs
- MenuAutomationPeer.cs
- MSAAWinEventWrap.cs
- XmlSiteMapProvider.cs
- TreeNodeCollection.cs
- CheckoutException.cs
- AuthenticationModulesSection.cs
- SymbolEqualComparer.cs
- Utils.cs
- DiscoveryDocumentReference.cs
- WebEncodingValidator.cs
- NavigationService.cs
- MenuItem.cs
- SortFieldComparer.cs
- Literal.cs
- FlowLayoutPanel.cs
- HttpRawResponse.cs
- EncodingDataItem.cs
- MatrixConverter.cs
- ReadOnlyCollection.cs
- _NativeSSPI.cs
- initElementDictionary.cs
- XslAstAnalyzer.cs
- HtmlTableCellCollection.cs
- CreateParams.cs
- CodeMemberField.cs
- FilterElement.cs
- EntityUtil.cs
- HttpServerVarsCollection.cs
- WebRequestModulesSection.cs
- ReaderWriterLockWrapper.cs
- Visual3D.cs
- SqlEnums.cs
- InfoCardArgumentException.cs
- Html32TextWriter.cs
- OutputCacheModule.cs
- MediaTimeline.cs
- ImageBrush.cs
- AdapterDictionary.cs
- DataGridViewCellFormattingEventArgs.cs
- NCryptNative.cs
- DrawingBrush.cs
- EdmProviderManifest.cs
- MetadataUtilsSmi.cs
- MulticastOption.cs
- RemotingServices.cs
- SettingsContext.cs
- ComponentCollection.cs
- XmlSignatureProperties.cs
- DataTransferEventArgs.cs
- streamingZipPartStream.cs
- ConfigurationHandlersInstallComponent.cs
- ValidationError.cs
- SqlCharStream.cs
- entityreference_tresulttype.cs
- CodeAttributeDeclarationCollection.cs
- ReferenceService.cs
- TypeToken.cs
- WindowsSpinner.cs
- XPathNodeInfoAtom.cs
- TitleStyle.cs
- CollectionBuilder.cs
- XmlNodeChangedEventArgs.cs
- PtsPage.cs
- HtmlControl.cs
- WebPartEventArgs.cs
- OdbcPermission.cs
- COM2ColorConverter.cs
- Faults.cs
- Rotation3D.cs
- FileLoadException.cs
- QueryInterceptorAttribute.cs
- GatewayDefinition.cs
- VisualTreeUtils.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- AssemblyBuilder.cs
- ErrorItem.cs
- PageCache.cs
- ObjectMemberMapping.cs
- VBIdentifierDesigner.xaml.cs
- AtomEntry.cs
- ClaimTypes.cs
- CapabilitiesUse.cs
- SchemaMapping.cs
- TextSelection.cs