1 //---------------------------------------------------------------------
2 // <copyright file="StorageMappingFragment.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
13 using System.Collections.ObjectModel;
15 using System.Data.Metadata.Edm;
16 using System.Diagnostics;
18 namespace System.Data.Mapping {
20 /// Represents the metadata for mapping fragment.
21 /// A set of mapping fragments makes up the Set mappings( EntitySet, AssociationSet or CompositionSet )
22 /// Each MappingFragment provides mapping for those properties of a type that map to a single table.
25 /// For Example if conceptually you could represent the CS MSL file as following
27 /// --EntityContainerMapping ( CNorthwind-->SNorthwind )
28 /// --EntitySetMapping
29 /// --EntityTypeMapping
32 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
33 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
34 /// --EntityTypeMapping
37 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
38 /// --ComplexPropertyMap
39 /// --ComplexTypeMapping
40 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
41 /// --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata )
42 /// --DiscriminatorProperyMap ( constant value-->SMemberMetadata )
43 /// --ComplexTypeMapping
44 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
45 /// --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata )
46 /// --DiscriminatorProperyMap ( constant value-->SMemberMetadata )
47 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
48 /// --AssociationSetMapping
49 /// --AssociationTypeMapping
52 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
53 /// --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata )
55 /// --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
56 /// This class represents the metadata for all the mapping fragment elements in the
57 /// above example. Users can access all the top level constructs of
58 /// MappingFragment element like EntityKey map, Property Maps, Discriminator
59 /// property through this mapping fragment class.
61 internal class StorageMappingFragment {
64 /// Construct a new Mapping Fragment object
66 /// <param name="tableExtent"></param>
67 /// <param name="typeMapping"></param>
68 internal StorageMappingFragment(EntitySet tableExtent, StorageTypeMapping typeMapping, bool distinctFlag) {
69 Debug.Assert(tableExtent != null, "Table should not be null when constructing a Mapping Fragment");
70 Debug.Assert(typeMapping != null, "TypeMapping should not be null when constructing a Mapping Fragment");
71 this.m_tableExtent = tableExtent;
72 this.m_typeMapping = typeMapping;
73 this.m_isSQueryDistinct = distinctFlag;
79 /// Table extent from which the properties are mapped under this fragment.
81 EntitySet m_tableExtent;
83 /// Type mapping under which this mapping fragment exists.
85 StorageTypeMapping m_typeMapping;
87 /// Condition property mappings for this mapping fragment.
89 Dictionary<EdmProperty, StoragePropertyMapping> m_conditionProperties = new Dictionary<EdmProperty, StoragePropertyMapping>(EqualityComparer<EdmProperty>.Default);
91 /// All the other properties .
93 List<StoragePropertyMapping> m_properties = new List<StoragePropertyMapping>();
95 /// Line Number for MappingFragment element start tag.
97 int m_startLineNumber;
99 /// Line position for MappingFragment element start tag.
101 int m_startLinePosition;
102 bool m_isSQueryDistinct;
107 /// The table from which the properties are mapped in this fragment
109 internal EntitySet TableSet {
111 return this.m_tableExtent;
115 internal bool IsSQueryDistinct
117 get { return m_isSQueryDistinct; }
121 /// Returns all the property mappings defined in the complex type mapping
122 /// including Properties and Condition Properties
124 internal ReadOnlyCollection<StoragePropertyMapping> AllProperties
128 List<StoragePropertyMapping> properties = new List<StoragePropertyMapping>();
129 properties.AddRange(m_properties);
130 properties.AddRange(m_conditionProperties.Values);
131 return properties.AsReadOnly();
136 /// Returns all the property mappings defined in the complex type mapping
137 /// including Properties and Condition Properties
139 internal ReadOnlyCollection<StoragePropertyMapping> Properties
143 return m_properties.AsReadOnly();
148 /// Line Number in MSL file where the Mapping Fragment Element's Start Tag is present.
150 internal int StartLineNumber {
152 return m_startLineNumber;
155 m_startLineNumber = value;
160 /// Line Position in MSL file where the Mapping Fragment Element's Start Tag is present.
162 internal int StartLinePosition {
164 return m_startLinePosition;
167 m_startLinePosition = value;
172 /// File URI of the MSL file
174 //This should not be stored on the Fragment. Probably it should go on schema.
175 //But this requires some thinking before we can finally decide where it should go.
176 internal string SourceLocation {
178 return this.m_typeMapping.SetMapping.EntityContainerMapping.SourceLocation;
185 /// Add a property mapping as a child of this mapping fragment
187 /// <param name="prop">child property mapping to be added</param>
188 internal void AddProperty(StoragePropertyMapping prop)
190 this.m_properties.Add(prop);
194 /// Add a condition property mapping as a child of this complex property mapping
195 /// Condition Property Mapping specifies a Condition either on the C side property or S side property.
197 /// <param name="conditionPropertyMap">The mapping that needs to be added</param>
198 internal void AddConditionProperty(StorageConditionPropertyMapping conditionPropertyMap, Action<EdmMember> duplicateMemberConditionError)
200 //Same Member can not have more than one Condition with in the
201 //same Mapping Fragment.
202 EdmProperty conditionMember = (conditionPropertyMap.EdmProperty != null) ? conditionPropertyMap.EdmProperty : conditionPropertyMap.ColumnProperty;
203 Debug.Assert(conditionMember != null);
204 if (!m_conditionProperties.ContainsKey(conditionMember))
206 m_conditionProperties.Add(conditionMember, conditionPropertyMap);
210 duplicateMemberConditionError(conditionMember);
215 /// This method is primarily for debugging purposes.
216 /// Will be removed shortly.
218 /// <param name="index"></param>
219 internal virtual void Print(int index) {
220 StorageEntityContainerMapping.GetPrettyPrintString(ref index);
221 StringBuilder sb = new StringBuilder();
222 sb.Append("MappingFragment");
224 sb.Append("Table Name:");
225 sb.Append(this.m_tableExtent.Name);
227 Console.WriteLine(sb.ToString());
228 foreach (StorageConditionPropertyMapping conditionMap in m_conditionProperties.Values)
229 (conditionMap).Print(index + 5);
230 foreach (StoragePropertyMapping propertyMapping in m_properties)
232 propertyMapping.Print(index + 5);