private static bool TryMatchEntityTypeConstructor(DbExpression then,
            Dictionary<EdmProperty, DbExpression> propertyMap,
            Dictionary<Query.InternalTrees.RelProperty, DbExpression> relPropertyMap,
            Dictionary<EntityType, List<Query.InternalTrees.RelProperty>> typeToRelPropertyMap,
            out EntityType entityType)
        {
            if (then.ExpressionKind != DbExpressionKind.NewInstance)
            {
                entityType = null;
                return false;
            }
            var constructor = (DbNewInstanceExpression)then;
            entityType = (EntityType)constructor.ResultType.EdmType;

            // process arguments to constructor (must be aligned across all case statements)
            Debug.Assert(entityType.Properties.Count == constructor.Arguments.Count, "invalid new instance");
            for (int j = 0; j < entityType.Properties.Count; j++)
            {
                var property = entityType.Properties[j];
                var assignment = constructor.Arguments[j];
                DbExpression existingAssignment;
                if (propertyMap.TryGetValue(property, out existingAssignment))
                {
                    if (!ExpressionsCompatible(assignment, existingAssignment)) { return false; }
                }
                else
                {
                    propertyMap.Add(property, assignment);
                }
            }

            // Now handle the rel properties
            if (constructor.HasRelatedEntityReferences)
            {
                List<Query.InternalTrees.RelProperty> relPropertyList;
                if (!typeToRelPropertyMap.TryGetValue(entityType, out relPropertyList))
                {
                    relPropertyList = new List<System.Data.Query.InternalTrees.RelProperty>();
                    typeToRelPropertyMap[entityType] = relPropertyList;
                }
                foreach (DbRelatedEntityRef relatedRef in constructor.RelatedEntityReferences)
                {
                    Query.InternalTrees.RelProperty relProperty = new System.Data.Query.InternalTrees.RelProperty((RelationshipType)relatedRef.TargetEnd.DeclaringType,
                        relatedRef.SourceEnd, relatedRef.TargetEnd);
                    DbExpression assignment = relatedRef.TargetEntityReference;
                    DbExpression existingAssignment;
                    if (relPropertyMap.TryGetValue(relProperty, out existingAssignment))
                    {
                        if (!ExpressionsCompatible(assignment, existingAssignment)) { return false; }
                    }
                    else
                    {
                        relPropertyMap.Add(relProperty, assignment);
                    }
                    relPropertyList.Add(relProperty);
                }
            }
            return true;
        }
예제 #2
0
        private static bool TryMatchEntityTypeConstructor(DbExpression then,
                                                          Dictionary <EdmProperty, DbExpression> propertyMap,
                                                          Dictionary <Query.InternalTrees.RelProperty, DbExpression> relPropertyMap,
                                                          Dictionary <EntityType, List <Query.InternalTrees.RelProperty> > typeToRelPropertyMap,
                                                          out EntityType entityType)
        {
            if (then.ExpressionKind != DbExpressionKind.NewInstance)
            {
                entityType = null;
                return(false);
            }
            var constructor = (DbNewInstanceExpression)then;

            entityType = (EntityType)constructor.ResultType.EdmType;

            // process arguments to constructor (must be aligned across all case statements)
            Debug.Assert(entityType.Properties.Count == constructor.Arguments.Count, "invalid new instance");
            for (int j = 0; j < entityType.Properties.Count; j++)
            {
                var          property   = entityType.Properties[j];
                var          assignment = constructor.Arguments[j];
                DbExpression existingAssignment;
                if (propertyMap.TryGetValue(property, out existingAssignment))
                {
                    if (!ExpressionsCompatible(assignment, existingAssignment))
                    {
                        return(false);
                    }
                }
                else
                {
                    propertyMap.Add(property, assignment);
                }
            }

            // Now handle the rel properties
            if (constructor.HasRelatedEntityReferences)
            {
                List <Query.InternalTrees.RelProperty> relPropertyList;
                if (!typeToRelPropertyMap.TryGetValue(entityType, out relPropertyList))
                {
                    relPropertyList = new List <System.Data.Query.InternalTrees.RelProperty>();
                    typeToRelPropertyMap[entityType] = relPropertyList;
                }
                foreach (DbRelatedEntityRef relatedRef in constructor.RelatedEntityReferences)
                {
                    Query.InternalTrees.RelProperty relProperty = new System.Data.Query.InternalTrees.RelProperty((RelationshipType)relatedRef.TargetEnd.DeclaringType,
                                                                                                                  relatedRef.SourceEnd, relatedRef.TargetEnd);
                    DbExpression assignment = relatedRef.TargetEntityReference;
                    DbExpression existingAssignment;
                    if (relPropertyMap.TryGetValue(relProperty, out existingAssignment))
                    {
                        if (!ExpressionsCompatible(assignment, existingAssignment))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        relPropertyMap.Add(relProperty, assignment);
                    }
                    relPropertyList.Add(relProperty);
                }
            }
            return(true);
        }