Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / EntityModel / SchemaObjectModel / ItemType.cs
1 //---------------------------------------------------------------------
2 // <copyright file="Item.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9
10 namespace System.Data.EntityModel.SchemaObjectModel
11 {
12     using System.Collections.Generic;
13     using System.Data.Metadata.Edm;
14     using System.Xml;
15
16     /// <summary>
17     /// Summary description for Item.
18     /// </summary>
19     [System.Diagnostics.DebuggerDisplay("Name={Name}, BaseType={BaseType.FQName}, HasKeys={HasKeys}")]
20     internal sealed class SchemaEntityType : StructuredType
21     {
22         #region Private Fields
23         
24         private const char KEY_DELIMITER = ' ';
25         private ISchemaElementLookUpTable<NavigationProperty> _navigationProperties = null;
26         private EntityKeyElement _keyElement = null;
27         private static List<PropertyRefElement> EmptyKeyProperties = new List<PropertyRefElement>(0);
28         #endregion
29         #region Public Methods
30         
31         /// <summary>
32         /// 
33         /// </summary>
34         /// <param name="parentElement"></param>
35         public SchemaEntityType(Schema parentElement)
36             : base(parentElement)
37         {
38             if (Schema.DataModel == SchemaDataModelOption.EntityDataModel)
39                 OtherContent.Add(Schema.SchemaSource);
40         }
41         
42         #endregion
43         #region Protected Methods
44
45         /// <summary>
46         /// 
47         /// </summary>
48         internal override void ResolveTopLevelNames()
49         {
50             base.ResolveTopLevelNames();
51
52             if (BaseType != null)
53             {
54                 if (!(BaseType is SchemaEntityType))
55                 {
56                     AddError(ErrorCode.InvalidBaseType, EdmSchemaErrorSeverity.Error,
57                         System.Data.Entity.Strings.InvalidBaseTypeForItemType(BaseType.FQName, FQName));
58                 }
59                 // Since the base type is not null, key must be defined on the base type
60                 else if (_keyElement != null && BaseType != null)
61                 {
62                     AddError(ErrorCode.InvalidKey, EdmSchemaErrorSeverity.Error,
63                         System.Data.Entity.Strings.InvalidKeyKeyDefinedInBaseClass(FQName, BaseType.FQName));
64                 }
65             }
66             // If the base type is not null, then the key must be defined on the base entity type, since
67             // we don't allow entity type without keys. 
68             else if (_keyElement == null)
69             {
70                 AddError(ErrorCode.KeyMissingOnEntityType, EdmSchemaErrorSeverity.Error,
71                     System.Data.Entity.Strings.KeyMissingOnEntityType(this.FQName));
72             }
73             else if (null == BaseType && null != UnresolvedBaseType)
74             {
75                 // this is already an error situation, we won't do any resolve name further in this type
76                 return;
77             }
78             else
79             {
80                 _keyElement.ResolveTopLevelNames();
81             }
82         }
83
84         #endregion
85         #region Protected Properties
86
87         protected override bool HandleAttribute(XmlReader reader)
88         {
89             if (base.HandleAttribute(reader))
90             {
91                 return true;
92             }
93             else if (CanHandleAttribute(reader, XmlConstants.OpenType) && Schema.DataModel == SchemaDataModelOption.EntityDataModel)
94             {
95                 // EF does not support this EDM 3.0 attribute, so ignore it.
96                 return true;
97             }
98
99             return false;
100         }
101
102         #endregion
103         #region Private Methods
104
105         #endregion
106         #region Public Properties
107
108         public EntityKeyElement KeyElement
109         {
110             get
111             {
112                 return _keyElement;
113             }
114         }
115
116         /// <summary>
117         /// 
118         /// </summary>
119         public IList<PropertyRefElement> DeclaredKeyProperties
120         {
121             get
122             {
123                 if (KeyElement == null)
124                 {
125                     return EmptyKeyProperties;
126                 }
127                 return KeyElement.KeyProperties;
128             }
129         }
130
131         /// <summary>
132         /// 
133         /// </summary>
134         /// <value></value>
135         public IList<PropertyRefElement> KeyProperties
136         {
137             get
138             {
139                 if (KeyElement == null)
140                 {
141                     if (BaseType != null)
142                     {
143                         System.Diagnostics.Debug.Assert(BaseType is SchemaEntityType, "ItemType.BaseType is not ItemType");
144                         return (BaseType as SchemaEntityType).KeyProperties;
145                     }
146
147                     return EmptyKeyProperties;
148                 }
149                 return this.KeyElement.KeyProperties;
150             }
151         }
152
153         /// <summary>
154         /// 
155         /// </summary>
156         public ISchemaElementLookUpTable<NavigationProperty> NavigationProperties
157         {
158             get
159             {
160                 if (_navigationProperties == null)
161                 {
162                     _navigationProperties = new FilteredSchemaElementLookUpTable<NavigationProperty, SchemaElement>(NamedMembers);
163                 }
164                 return _navigationProperties;
165             }
166         }
167         
168         #endregion
169         #region Protected Methods
170
171         /// <summary>
172         /// 
173         /// </summary>
174         internal override void Validate()
175         {
176             // structured type base class will validate all members (properties, nav props, etc)
177             base.Validate();
178
179             if (this.KeyElement != null)
180             {
181                 this.KeyElement.Validate();
182             }
183         }
184
185         #endregion
186         #region Protected Properties
187
188         protected override bool HandleElement(XmlReader reader)
189         {
190             if (base.HandleElement(reader))
191             {
192                 return true;
193             }
194             else if (CanHandleElement(reader, XmlConstants.Key))
195             {
196                 HandleKeyElement(reader);
197                 return true;
198             }
199             else if (CanHandleElement(reader, XmlConstants.NavigationProperty))
200             {
201                 HandleNavigationPropertyElement(reader);
202                 return true;
203             }
204             else if (CanHandleElement(reader, XmlConstants.ValueAnnotation) && Schema.DataModel == SchemaDataModelOption.EntityDataModel)
205             {
206                 // EF does not support this EDM 3.0 element, so ignore it.
207                 SkipElement(reader);
208                 return true;
209             }
210             else if (CanHandleElement(reader, XmlConstants.TypeAnnotation) && Schema.DataModel == SchemaDataModelOption.EntityDataModel)
211             {
212                 // EF does not support this EDM 3.0 element, so ignore it.
213                 SkipElement(reader);
214                 return true;
215             }
216             return false;
217         }
218
219         #endregion
220         #region Private Methods
221
222         /// <summary>
223         /// 
224         /// </summary>
225         /// <param name="reader"></param>
226         private void HandleNavigationPropertyElement(XmlReader reader)
227         {
228             NavigationProperty navigationProperty = new NavigationProperty(this);
229             navigationProperty.Parse(reader);
230             AddMember(navigationProperty);
231         }
232
233         /// <summary>
234         /// 
235         /// </summary>
236         /// <param name="reader"></param>
237         private void HandleKeyElement(XmlReader reader)
238         {
239             _keyElement = new EntityKeyElement(this);
240             _keyElement.Parse(reader);
241         }
242         #endregion
243     }
244 }