Пример #1
0
        internal DbQueryCommandTree GenerateFunctionView(out DiscriminatorMap discriminatorMap)
        {
            DebugCheck.NotNull(m_mappingItemCollection);

            discriminatorMap = null;

            // Prepare the direct call of the store function as StoreFunction(@EdmFunc_p1, ..., @EdmFunc_pN).
            // Note that function call arguments are command parameters created from the m_edmFunction parameters.
            Debug.Assert(TargetFunction != null, "this.TargetFunction != null");
            DbExpression storeFunctionInvoke = TargetFunction.Invoke(GetParametersForTargetFunctionCall());

            // Generate the query expression producing c-space result from s-space function call(s).
            DbExpression queryExpression;

            if (m_structuralTypeMappings != null)
            {
                queryExpression = GenerateStructuralTypeResultMappingView(storeFunctionInvoke, out discriminatorMap);
                Debug.Assert(
                    queryExpression != null &&
                    TypeSemantics.IsPromotableTo(queryExpression.ResultType, FunctionImport.ReturnParameter.TypeUsage),
                    "TypeSemantics.IsPromotableTo(queryExpression.ResultType, this.FunctionImport.ReturnParameter.TypeUsage)");
            }
            else
            {
                queryExpression = GenerateScalarResultMappingView(storeFunctionInvoke);
                Debug.Assert(
                    queryExpression != null &&
                    TypeSemantics.IsEqual(queryExpression.ResultType, FunctionImport.ReturnParameter.TypeUsage),
                    "TypeSemantics.IsEqual(queryExpression.ResultType, this.FunctionImport.ReturnParameter.TypeUsage)");
            }

            // Generate parameterized command, where command parameters are semantically the c-space function parameters.
            return(DbQueryCommandTree.FromValidExpression(
                       m_mappingItemCollection.Workspace, TargetPerspective.TargetPerspectiveDataSpace, queryExpression));
        }
 internal ExplicitDiscriminatorMap(DiscriminatorMap template)
 {
     m_typeMap = template.TypeMap;
     m_discriminatorProperty = template.Discriminator.Property;
     m_properties            = new ReadOnlyCollection <EdmProperty>(template.PropertyMap.Select(propertyValuePair => propertyValuePair.Key)
                                                                    .ToList());
 }
Пример #3
0
 internal ExplicitDiscriminatorMap(DiscriminatorMap template)
 {
     m_typeMap = template.TypeMap;
     m_discriminatorProperty = template.Discriminator.Property;
     m_properties            = template.PropertyMap.Select(propertyValuePair => propertyValuePair.Key)
                               .ToList().AsReadOnly();
 }
Пример #4
0
        internal DbQueryCommandTree GenerateFunctionView(
            out DiscriminatorMap discriminatorMap)
        {
            discriminatorMap = (DiscriminatorMap)null;
            DbExpression storeFunctionInvoke = (DbExpression)this.TargetFunction.Invoke(this.GetParametersForTargetFunctionCall());

            return(DbQueryCommandTree.FromValidExpression(this._containerMapping.StorageMappingItemCollection.Workspace, DataSpace.SSpace, this.m_structuralTypeMappings == null ? this.GenerateScalarResultMappingView(storeFunctionInvoke) : this.GenerateStructuralTypeResultMappingView(storeFunctionInvoke, out discriminatorMap), true));
        }
Пример #5
0
        private DbExpression GenerateStructuralTypeResultMappingView(
            DbExpression storeFunctionInvoke,
            out DiscriminatorMap discriminatorMap)
        {
            discriminatorMap = (DiscriminatorMap)null;
            DbExpression dbExpression = storeFunctionInvoke;
            DbExpression queryView;

            if (this.m_structuralTypeMappings.Count == 1)
            {
                Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > structuralTypeMapping = this.m_structuralTypeMappings[0];
                StructuralType structuralType = structuralTypeMapping.Item1;
                List <ConditionPropertyMapping> conditions       = structuralTypeMapping.Item2;
                List <PropertyMapping>          propertyMappings = structuralTypeMapping.Item3;
                if (conditions.Count > 0)
                {
                    dbExpression = (DbExpression)dbExpression.Where((Func <DbExpression, DbExpression>)(row => FunctionImportMappingComposable.GenerateStructuralTypeConditionsPredicate(conditions, row)));
                }
                DbExpressionBinding input = dbExpression.BindAs("row");
                DbExpression        structuralTypeMappingView = FunctionImportMappingComposable.GenerateStructuralTypeMappingView(structuralType, propertyMappings, (DbExpression)input.Variable);
                queryView = (DbExpression)input.Project(structuralTypeMappingView);
            }
            else
            {
                DbExpressionBinding binding = dbExpression.BindAs("row");
                List <DbExpression> list    = this.m_structuralTypeMappings.Select <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> >, DbExpression>((Func <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> >, DbExpression>)(m => FunctionImportMappingComposable.GenerateStructuralTypeConditionsPredicate(m.Item2, (DbExpression)binding.Variable))).ToList <DbExpression>();
                binding = binding.Filter(Helpers.BuildBalancedTreeInPlace <DbExpression>((IList <DbExpression>)list.ToArray(), (Func <DbExpression, DbExpression, DbExpression>)((prev, next) => (DbExpression)prev.Or(next)))).BindAs("row");
                List <DbExpression> source = new List <DbExpression>(this.m_structuralTypeMappings.Count);
                foreach (Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > structuralTypeMapping in this.m_structuralTypeMappings)
                {
                    StructuralType         structuralType   = structuralTypeMapping.Item1;
                    List <PropertyMapping> propertyMappings = structuralTypeMapping.Item3;
                    source.Add(FunctionImportMappingComposable.GenerateStructuralTypeMappingView(structuralType, propertyMappings, (DbExpression)binding.Variable));
                }
                DbExpression projection = (DbExpression)DbExpressionBuilder.Case(list.Take <DbExpression>(this.m_structuralTypeMappings.Count - 1), source.Take <DbExpression>(this.m_structuralTypeMappings.Count - 1), source[this.m_structuralTypeMappings.Count - 1]);
                queryView = (DbExpression)binding.Project(projection);
                DiscriminatorMap.TryCreateDiscriminatorMap(this.FunctionImport.EntitySet, queryView, out discriminatorMap);
            }
            return(queryView);
        }
        private DbExpression GenerateStructuralTypeResultMappingView(
            DbExpression storeFunctionInvoke, out DiscriminatorMap discriminatorMap)
        {
            Debug.Assert(
                m_structuralTypeMappings != null && m_structuralTypeMappings.Count > 0,
                "m_structuralTypeMappings != null && m_structuralTypeMappings.Count > 0");

            discriminatorMap = null;

            // Process explicit structural type mappings. The mapping is based on the direct call of the store function
            // wrapped into a projection constructing the mapped structural types.

            var queryExpression = storeFunctionInvoke;

            if (m_structuralTypeMappings.Count == 1)
            {
                var mapping = m_structuralTypeMappings[0];

                var type             = mapping.Item1;
                var conditions       = mapping.Item2;
                var propertyMappings = mapping.Item3;

                if (conditions.Count > 0)
                {
                    queryExpression = queryExpression.Where((row) => GenerateStructuralTypeConditionsPredicate(conditions, row));
                }

                var binding = queryExpression.BindAs("row");
                var entityTypeMappingView = GenerateStructuralTypeMappingView(type, propertyMappings, binding.Variable);

                queryExpression = binding.Project(entityTypeMappingView);
            }
            else
            {
                var binding = queryExpression.BindAs("row");

                // Make sure type projection is performed over a closed set where each row is guaranteed to produce a known type.
                // To do this, filter the store function output using the type conditions.
                Debug.Assert(m_structuralTypeMappings.All(m => m.Item2.Count > 0), "In multi-type mapping each type must have conditions.");
                var structuralTypePredicates =
                    m_structuralTypeMappings.Select(m => GenerateStructuralTypeConditionsPredicate(m.Item2, binding.Variable)).ToList();
                queryExpression = binding.Filter(
                    Helpers.BuildBalancedTreeInPlace(
                        structuralTypePredicates.ToArray(), // clone, otherwise BuildBalancedTreeInPlace will change it
                        (prev, next) => prev.Or(next)));
                binding = queryExpression.BindAs("row");

                var structuralTypeMappingViews = new List <DbExpression>(m_structuralTypeMappings.Count);
                foreach (var mapping in m_structuralTypeMappings)
                {
                    var type             = mapping.Item1;
                    var propertyMappings = mapping.Item3;

                    structuralTypeMappingViews.Add(GenerateStructuralTypeMappingView(type, propertyMappings, binding.Variable));
                }
                Debug.Assert(
                    structuralTypeMappingViews.Count == structuralTypePredicates.Count,
                    "structuralTypeMappingViews.Count == structuralTypePredicates.Count");

                // Because we are projecting over the closed set, we can convert the last WHEN THEN into ELSE.
                DbExpression typeConstructors = DbExpressionBuilder.Case(
                    structuralTypePredicates.Take(m_structuralTypeMappings.Count - 1),
                    structuralTypeMappingViews.Take(m_structuralTypeMappings.Count - 1),
                    structuralTypeMappingViews[m_structuralTypeMappings.Count - 1]);

                queryExpression = binding.Project(typeConstructors);

                if (DiscriminatorMap.TryCreateDiscriminatorMap(FunctionImport.EntitySet, queryExpression, out discriminatorMap))
                {
                    Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                }
            }

            return(queryExpression);
        }
Пример #7
0
 internal ExplicitDiscriminatorMap(DiscriminatorMap template)
 {
     this.m_typeMap = template.TypeMap;
     this.m_discriminatorProperty = template.Discriminator.Property;
     this.m_properties            = new ReadOnlyCollection <EdmProperty>((IList <EdmProperty>)template.PropertyMap.Select <KeyValuePair <EdmProperty, DbExpression>, EdmProperty>((Func <KeyValuePair <EdmProperty, DbExpression>, EdmProperty>)(propertyValuePair => propertyValuePair.Key)).ToList <EdmProperty>());
 }