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()); }
internal ExplicitDiscriminatorMap(DiscriminatorMap template) { m_typeMap = template.TypeMap; m_discriminatorProperty = template.Discriminator.Property; m_properties = template.PropertyMap.Select(propertyValuePair => propertyValuePair.Key) .ToList().AsReadOnly(); }
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)); }
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); }
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>()); }