Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / EntityModel / SchemaObjectModel / EntityContainerEntitySet.cs
1 //---------------------------------------------------------------------
2 // <copyright file="EntityContainerEntitySet.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.Data.Entity;
13     using System.Data.Metadata.Edm;
14     using System.Diagnostics;
15     using System.Xml;
16     
17     /// <summary>
18     /// Represents an EntitySet element.
19     /// </summary>
20     internal sealed class EntityContainerEntitySet : SchemaElement
21     {
22         private SchemaEntityType _entityType = null;
23         private string _unresolvedEntityTypeName = null;
24         private string _schema = null;
25         private string _table = null;
26         private EntityContainerEntitySetDefiningQuery _definingQueryElement = null;
27
28       
29         /// <summary>
30         /// Constructs an EntityContainerEntitySet
31         /// </summary>
32         /// <param name="parentElement">Reference to the schema element.</param>
33         public EntityContainerEntitySet( EntityContainer parentElement )
34             : base( parentElement )
35         {
36         }
37
38         public override string FQName
39         {
40             get
41             {
42                 return this.ParentElement.Name + "." + this.Name;
43             }
44         }
45
46         public SchemaEntityType EntityType
47         {
48             get
49             {
50                 return _entityType;
51             }
52         }
53
54         public string DbSchema
55         {
56             get
57             {
58                 return _schema;
59             }
60         }
61
62         public string Table
63         {
64             get
65             {
66                 return _table;
67             }
68         }
69
70         public string DefiningQuery
71         {
72             get 
73             {
74                 if (_definingQueryElement != null)
75                 {
76                     return _definingQueryElement.Query;
77                 }
78                 return null;
79             }
80         }
81
82         protected override bool HandleElement(XmlReader reader)
83         {
84             if (base.HandleElement(reader))
85             {
86                 return true;
87             }
88             else if (Schema.DataModel == SchemaDataModelOption.ProviderDataModel)
89             {
90                 if (CanHandleElement(reader, XmlConstants.DefiningQuery))
91                 {
92                     HandleDefiningQueryElement(reader);
93                     return true;
94                 }
95             }
96             else if (Schema.DataModel == SchemaDataModelOption.EntityDataModel)
97             {
98                 if (CanHandleElement(reader, XmlConstants.ValueAnnotation))
99                 {
100                     // EF does not support this EDM 3.0 element, so ignore it.
101                     SkipElement(reader);
102                     return true;
103                 }
104                 else if (CanHandleElement(reader, XmlConstants.TypeAnnotation))
105                 {
106                     // EF does not support this EDM 3.0 element, so ignore it.
107                     SkipElement(reader);
108                     return true;
109                 }
110             }
111             return false;
112         }
113
114         protected override bool HandleAttribute(XmlReader reader)
115         {
116             if (base.HandleAttribute(reader))
117             {
118                 return true;
119             }
120             else if (CanHandleAttribute(reader, XmlConstants.EntityType))
121             {
122                 HandleEntityTypeAttribute(reader);
123                 return true;
124             }
125             if (Schema.DataModel == SchemaDataModelOption.ProviderDataModel)
126             {
127                 if (CanHandleAttribute(reader, XmlConstants.Schema))
128                 {
129                     HandleDbSchemaAttribute(reader);
130                     return true;
131                 }
132                 else if (CanHandleAttribute(reader, XmlConstants.Table))
133                 {
134                     HandleTableAttribute(reader);
135                     return true;
136                 }
137             }
138             return false;
139         }
140
141         private void HandleDefiningQueryElement(XmlReader reader)
142         {
143             Debug.Assert(reader != null);
144
145             EntityContainerEntitySetDefiningQuery query = new EntityContainerEntitySetDefiningQuery(this);
146             query.Parse(reader);
147             _definingQueryElement = query;
148         }
149
150         protected override void HandleNameAttribute(XmlReader reader)
151         {
152             if (Schema.DataModel == SchemaDataModelOption.ProviderDataModel)
153             {
154                 // ssdl will take anything, because this is the table name, and we
155                 // can't predict what the vendor will need in a table name
156                 Name = reader.Value;
157             }
158             else
159             {
160                 base.HandleNameAttribute(reader);
161             }
162         }
163         /// <summary>
164         /// The method that is called when a Type attribute is encountered.
165         /// </summary>
166         /// <param name="reader">An XmlReader positioned at the Type attribute.</param>
167         private void HandleEntityTypeAttribute( XmlReader reader )
168         {
169             Debug.Assert( reader != null );
170
171             ReturnValue<string> value = HandleDottedNameAttribute( reader, _unresolvedEntityTypeName, Strings.PropertyTypeAlreadyDefined );
172             if ( value.Succeeded )
173             {
174                 _unresolvedEntityTypeName = value.Value;
175             }
176         }
177
178         /// <summary>
179         /// The method that is called when a DbSchema attribute is encountered.
180         /// </summary>
181         /// <param name="reader">An XmlReader positioned at the Type attribute.</param>
182         private void HandleDbSchemaAttribute( XmlReader reader )
183         {
184             Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderDataModel, "We shouldn't see this attribute unless we are parsing ssdl");
185             Debug.Assert( reader != null );
186
187              _schema = reader.Value;
188         }
189
190         /// <summary>
191         /// The method that is called when a DbTable attribute is encountered.
192         /// </summary>
193         /// <param name="reader">An XmlReader positioned at the Type attribute.</param>
194         private void HandleTableAttribute( XmlReader reader )
195         {
196             Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderDataModel, "We shouldn't see this attribute unless we are parsing ssdl");
197             Debug.Assert( reader != null );
198
199              _table = reader.Value;
200         }
201         
202         
203         /// <summary>
204         /// Used during the resolve phase to resolve the type name to the object that represents that type
205         /// </summary>
206         internal override void ResolveTopLevelNames()
207         {
208             base.ResolveTopLevelNames();
209
210             if ( _entityType == null )
211             {
212                 SchemaType type = null;
213                 if ( ! Schema.ResolveTypeName( this, _unresolvedEntityTypeName, out type) )
214                 {
215                     return;
216                 }
217
218                 _entityType = type as SchemaEntityType;
219                 if ( _entityType == null )
220                 {
221                     AddError( ErrorCode.InvalidPropertyType, EdmSchemaErrorSeverity.Error,
222                         System.Data.Entity.Strings.InvalidEntitySetType(_unresolvedEntityTypeName ) );
223                     return;
224                 }
225             }
226         }
227
228         internal override void Validate()
229         {
230             base.Validate();
231
232             if (_entityType.KeyProperties.Count == 0)
233             {
234                 AddError(ErrorCode.EntitySetTypeHasNoKeys, EdmSchemaErrorSeverity.Error,
235                     System.Data.Entity.Strings.EntitySetTypeHasNoKeys(Name, _entityType.FQName));
236             }
237
238             if (_definingQueryElement != null)
239             {
240                 _definingQueryElement.Validate();
241
242                 if (DbSchema != null || Table != null)
243                 {
244                     AddError(ErrorCode.TableAndSchemaAreMutuallyExclusiveWithDefiningQuery, EdmSchemaErrorSeverity.Error,
245                         System.Data.Entity.Strings.TableAndSchemaAreMutuallyExclusiveWithDefiningQuery(FQName));
246                 }
247             }
248         }
249
250         internal override SchemaElement Clone(SchemaElement parentElement)
251         {
252             EntityContainerEntitySet entitySet = new EntityContainerEntitySet((EntityContainer)parentElement);
253             entitySet._definingQueryElement = this._definingQueryElement;
254             entitySet._entityType = this._entityType;
255             entitySet._schema = this._schema;
256             entitySet._table = this._table;
257             entitySet.Name = this.Name;
258
259             return entitySet;
260         }
261    }
262 }