Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.Linq / Mapping / MetaModel.cs
blob68b69b3defc7a9e8777e007621aba1eb9cdf8782
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Collections.ObjectModel;
5 using System.Data.Linq;
6 using System.Linq.Expressions;
7 using System.Reflection;
8 using System.Text;
9 using System.Linq;
10 using System.Diagnostics.CodeAnalysis;
12 namespace System.Data.Linq.Mapping {
13 /// <summary>
14 /// A MetaModel is an abstraction representing the mapping between a database and domain objects
15 /// </summary>
16 public abstract class MetaModel {
17 /// <summary>
18 /// The mapping source that originated this model.
19 /// </summary>
20 public abstract MappingSource MappingSource { get; }
21 /// <summary>
22 /// The type of DataContext type this model describes.
23 /// </summary>
24 public abstract Type ContextType { get; }
25 /// <summary>
26 /// The name of the database.
27 /// </summary>
28 public abstract string DatabaseName { get; }
29 /// <summary>
30 /// The CLR type that implements IProvider to use as a provider.
31 /// </summary>
32 public abstract Type ProviderType { get; }
33 /// <summary>
34 /// Gets the MetaTable associated with a given type.
35 /// </summary>
36 /// <param name="rowType">The CLR row type.</param>
37 /// <returns>The MetaTable if one exists, otherwise null.</returns>
38 public abstract MetaTable GetTable(Type rowType);
39 /// <summary>
40 /// Gets the MetaFunction corresponding to a database function: user-defined function, table-valued function or stored-procedure.
41 /// </summary>
42 /// <param name="method">The method defined on the DataContext or subordinate class that represents the database function.</param>
43 /// <returns>The MetaFunction if one exists, otherwise null.</returns>
44 public abstract MetaFunction GetFunction(MethodInfo method);
45 /// <summary>
46 /// Get an enumeration of all tables.
47 /// </summary>
48 /// <returns>An enumeration of all the MetaTables</returns>
49 [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification="Non-trivial operations are not suitable for properties.")]
50 public abstract IEnumerable<MetaTable> GetTables();
51 /// <summary>
52 /// Get an enumeration of all functions.
53 /// </summary>
54 /// <returns>An enumeration of all the MetaFunctions</returns>
55 [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification="Non-trivial operations are not suitable for properties.")]
56 public abstract IEnumerable<MetaFunction> GetFunctions();
57 /// <summary>
58 /// This method discovers the MetaType for the given Type.
59 /// </summary>
60 public abstract MetaType GetMetaType(Type type);
61 /// <summary>
62 /// Internal value used to determine a reference identity for comparing meta models
63 /// without needing to keep track of the actual meta model reference.
64 /// </summary>
65 private object identity = new object();
66 internal object Identity {
67 get { return this.identity; }
71 /// <summary>
72 /// A MetaTable represents an abstraction of a database table (or view)
73 /// </summary>
74 public abstract class MetaTable {
75 /// <summary>
76 /// The MetaModel containing this MetaTable.
77 /// </summary>
78 public abstract MetaModel Model { get; }
79 /// <summary>
80 /// The name of the table as defined by the database.
81 /// </summary>
82 public abstract string TableName { get; }
83 /// <summary>
84 /// The MetaType describing the type of the rows of the table.
85 /// </summary>
86 public abstract MetaType RowType { get; }
87 /// <summary>
88 /// The DataContext method used to perform insert operations
89 /// </summary>
90 public abstract MethodInfo InsertMethod { get; }
91 /// <summary>
92 /// The DataContext method used to perform update operations
93 /// </summary>
94 public abstract MethodInfo UpdateMethod { get; }
95 /// <summary>
96 /// The DataContext method used to perform delete operations
97 /// </summary>
98 public abstract MethodInfo DeleteMethod { get; }
101 /// <summary>
102 /// A MetaType represents the mapping of a domain object type onto a database table's columns.
103 /// </summary>
104 public abstract class MetaType {
105 /// <summary>
106 /// The MetaModel containing this MetaType.
107 /// </summary>
108 public abstract MetaModel Model { get; }
109 /// <summary>
110 /// The MetaTable using this MetaType for row definition.
111 /// </summary>
112 public abstract MetaTable Table { get; }
113 /// <summary>
114 /// The underlying CLR type.
115 /// </summary>
116 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The contexts in which this is available are fairly specific.")]
117 public abstract Type Type { get; }
118 /// <summary>
119 /// The name of the MetaType (same as the CLR type's name).
120 /// </summary>
121 public abstract string Name { get; }
122 /// <summary>
123 /// True if the MetaType is an entity type.
124 /// </summary>
125 public abstract bool IsEntity { get; }
126 /// <summary>
127 /// True if the underlying type can be instantiated as the result of a query.
128 /// </summary>
129 public abstract bool CanInstantiate { get; }
130 /// <summary>
131 /// The member that represents the auto-generated identity column, or null if there is none.
132 /// </summary>
133 public abstract MetaDataMember DBGeneratedIdentityMember { get; }
134 /// <summary>
135 /// The member that represents the row-version or timestamp column, or null if there is none.
136 /// </summary>
137 public abstract MetaDataMember VersionMember { get; }
138 /// <summary>
139 /// The member that represents the inheritance discriminator column, or null if there is none.
140 /// </summary>
141 public abstract MetaDataMember Discriminator { get; }
142 /// <summary>
143 /// True if the type has any persistent member with an UpdateCheck policy other than Never.
144 /// </summary>
145 public abstract bool HasUpdateCheck { get; }
146 /// <summary>
147 /// True if the type is part of a mapped inheritance hierarchy.
148 /// </summary>
149 public abstract bool HasInheritance { get; }
150 /// <summary>
151 /// True if this type defines an inheritance code.
152 /// </summary>
153 public abstract bool HasInheritanceCode { get; }
154 /// <summary>
155 /// The inheritance code defined by this type.
156 /// </summary>
157 public abstract object InheritanceCode { get; }
158 /// <summary>
159 /// True if this type is used as the default of an inheritance hierarchy.
160 /// </summary>
161 public abstract bool IsInheritanceDefault { get; }
162 /// <summary>
163 /// The root type of the inheritance hierarchy.
164 /// </summary>
165 public abstract MetaType InheritanceRoot { get; }
166 /// <summary>
167 /// The base metatype in the inheritance hierarchy.
168 /// </summary>
169 public abstract MetaType InheritanceBase { get; }
170 /// <summary>
171 /// The type that is the default of the inheritance hierarchy.
172 /// </summary>
173 public abstract MetaType InheritanceDefault { get; }
174 /// <summary>
175 /// Gets the MetaType for an inheritance sub type.
176 /// </summary>
177 /// <param name="type">The root or sub type of the inheritance hierarchy.</param>
178 /// <returns>The MetaType.</returns>
179 public abstract MetaType GetInheritanceType(Type type);
180 /// <summary>
181 /// Gets type associated with the specified inheritance code.
182 /// </summary>
183 /// <param name="code">The inheritance code</param>
184 /// <returns>The MetaType.</returns>
185 public abstract MetaType GetTypeForInheritanceCode(object code);
186 /// <summary>
187 /// Gets an enumeration of all types defined by an inheritance hierarchy.
188 /// </summary>
189 /// <returns>Enumeration of MetaTypes.</returns>
190 public abstract ReadOnlyCollection<MetaType> InheritanceTypes { get; }
191 /// <summary>
192 /// Returns true if the MetaType or any base MetaType has an OnLoaded method.
193 /// </summary>
194 public abstract bool HasAnyLoadMethod { get; }
195 /// <summary>
196 /// Returns true if the MetaType or any base MetaType has an OnValidate method.
197 /// </summary>
198 public abstract bool HasAnyValidateMethod { get; }
199 /// <summary>
200 /// Gets an enumeration of the immediate derived types in an inheritance hierarchy.
201 /// </summary>
202 /// <returns>Enumeration of MetaTypes.</returns>
203 public abstract ReadOnlyCollection<MetaType> DerivedTypes { get; }
204 /// <summary>
205 /// Gets an enumeration of all the data members (fields and properties).
206 /// </summary>
207 public abstract ReadOnlyCollection<MetaDataMember> DataMembers { get; }
208 /// <summary>
209 /// Gets an enumeration of all the persistent data members (fields and properties mapped into database columns).
210 /// </summary>
211 public abstract ReadOnlyCollection<MetaDataMember> PersistentDataMembers { get; }
212 /// <summary>
213 /// Gets an enumeration of all the data members that define up the unique identity of the type.
214 /// </summary>
215 public abstract ReadOnlyCollection<MetaDataMember> IdentityMembers { get; }
216 /// <summary>
217 /// Gets an enumeration of all the associations.
218 /// </summary>
219 public abstract ReadOnlyCollection<MetaAssociation> Associations { get; }
220 /// <summary>
221 /// Gets the MetaDataMember associated with the specified member.
222 /// </summary>
223 /// <param name="member">The CLR member.</param>
224 /// <returns>The MetaDataMember if there is one, otherwise null.</returns>
225 public abstract MetaDataMember GetDataMember(MemberInfo member);
226 /// <summary>
227 /// The method called when the entity is first loaded.
228 /// </summary>
229 public abstract MethodInfo OnLoadedMethod { get; }
230 /// <summary>
231 /// The method called to ensure the entity is in a valid state.
232 /// </summary>
233 public abstract MethodInfo OnValidateMethod { get; }
236 /// <summary>
237 /// A MetaDataMember represents the mapping between a domain object's field or property into a database table's column.
238 /// </summary>
239 [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "MetaData", Justification = "The capitalization was deliberately chosen.")]
240 public abstract class MetaDataMember {
241 /// <summary>
242 /// The MetaType containing this data member.
243 /// </summary>
244 public abstract MetaType DeclaringType { get; }
245 /// <summary>
246 /// The underlying MemberInfo.
247 /// </summary>
248 public abstract MemberInfo Member { get; }
249 /// <summary>
250 /// The member that actually stores this member's data.
251 /// </summary>
252 public abstract MemberInfo StorageMember { get; }
253 /// <summary>
254 /// The name of the member, same as the MemberInfo name.
255 /// </summary>
256 public abstract string Name { get; }
257 /// <summary>
258 /// The name of the column (or constraint) in the database.
259 /// </summary>
260 public abstract string MappedName { get; }
261 /// <summary>
262 /// The oridinal position of this member in the default layout of query results.
263 /// </summary>
264 public abstract int Ordinal { get; }
265 /// <summary>
266 /// The type of this member.
267 /// </summary>
268 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The contexts in which this is available are fairly specific.")]
269 public abstract Type Type { get; }
270 /// <summary>
271 /// True if this member is declared by the specified type.
272 /// </summary>
273 /// <param name="type">Type to check.</param>
274 public abstract bool IsDeclaredBy(MetaType type);
275 /// <summary>
276 /// The accessor used to get/set the value of this member.
277 /// </summary>
278 public abstract MetaAccessor MemberAccessor { get; }
279 /// <summary>
280 /// The accessor used to get/set the storage value of this member.
281 /// </summary>
282 public abstract MetaAccessor StorageAccessor { get; }
283 /// <summary>
284 /// The accessor used to get/set the deferred value of this member (without causing fetch).
285 /// </summary>
286 public abstract MetaAccessor DeferredValueAccessor { get; }
287 /// <summary>
288 /// The accessor used to get/set the deferred source of this member.
289 /// </summary>
290 public abstract MetaAccessor DeferredSourceAccessor { get; }
291 /// <summary>
292 /// True if this member is defer-loaded by default.
293 /// </summary>
294 public abstract bool IsDeferred { get; }
295 /// <summary>
296 /// True if this member is mapped to a column (or constraint).
297 /// </summary>
298 public abstract bool IsPersistent { get; }
299 /// <summary>
300 /// True if this member defines an association relationship.
301 /// </summary>
302 public abstract bool IsAssociation { get; }
303 /// <summary>
304 /// True if this member is part of the type's identity.
305 /// </summary>
306 public abstract bool IsPrimaryKey { get; }
307 /// <summary>
308 /// True if this member is automatically generated by the database.
309 /// </summary>
310 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db", Justification = "Conforms to legacy spelling.")]
311 public abstract bool IsDbGenerated { get; }
312 /// <summary>
313 /// True if this member represents the row version or timestamp.
314 /// </summary>
315 public abstract bool IsVersion { get; }
316 /// <summary>
317 /// True if this member represents the inheritance discriminator.
318 /// </summary>
319 public abstract bool IsDiscriminator { get; }
320 /// <summary>
321 /// True if this member's value can be assigned the null value.
322 /// </summary>
323 public abstract bool CanBeNull { get; }
324 /// <summary>
325 /// The type of the database column.
326 /// </summary>
327 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db", Justification = "Conforms to legacy spelling.")]
328 public abstract string DbType { get; }
329 /// <summary>
330 /// Expression defining a computed column.
331 /// </summary>
332 public abstract string Expression { get; }
333 /// <summary>
334 /// The optimistic concurrency check policy for this member.
335 /// </summary>
336 public abstract UpdateCheck UpdateCheck { get; }
337 /// <summary>
338 /// Specifies for inserts and updates when this member should be read back after the
339 /// operation completes.
340 /// </summary>
341 public abstract AutoSync AutoSync { get; }
342 /// <summary>
343 /// The MetaAssociation corresponding to this member, or null if there is none.
344 /// </summary>
345 public abstract MetaAssociation Association { get; }
346 /// <summary>
347 /// The DataContext method used to perform load operations
348 /// </summary>
349 public abstract MethodInfo LoadMethod { get; }
352 /// <summary>
353 /// A MetaFunction represents the mapping between a context method and a database function.
354 /// </summary>
355 public abstract class MetaFunction {
356 /// <summary>
357 /// The MetaModel containing this function.
358 /// </summary>
359 public abstract MetaModel Model { get; }
360 /// <summary>
361 /// The underlying context method.
362 /// </summary>
363 public abstract MethodInfo Method { get; }
364 /// <summary>
365 /// The name of the method (same as the MethodInfo's name).
366 /// </summary>
367 public abstract string Name { get; }
368 /// <summary>
369 /// The name of the database function or procedure.
370 /// </summary>
371 public abstract string MappedName { get; }
372 /// <summary>
373 /// True if the function can be composed within a query
374 /// </summary>
375 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Composable", Justification="Spelling is correct.")]
376 public abstract bool IsComposable { get; }
377 /// <summary>
378 /// Gets an enumeration of the function parameters.
379 /// </summary>
380 /// <returns></returns>
381 public abstract ReadOnlyCollection<MetaParameter> Parameters { get; }
382 /// <summary>
383 /// The return parameter
384 /// </summary>
385 public abstract MetaParameter ReturnParameter { get; }
386 /// <summary>
387 /// True if the stored procedure has multiple result types.
388 /// </summary>
389 public abstract bool HasMultipleResults { get; }
390 /// <summary>
391 /// An enumeration of all the known result row types of a stored-procedure.
392 /// </summary>
393 /// <returns>Enumeration of possible result row types.</returns>
394 public abstract ReadOnlyCollection<MetaType> ResultRowTypes { get; }
397 /// <summary>
398 /// A MetaParameter represents the mapping between a method parameter and a database function parameter.
399 /// </summary>
400 public abstract class MetaParameter {
401 /// <summary>
402 /// The underlying method parameter.
403 /// </summary>
404 public abstract ParameterInfo Parameter { get; }
405 /// <summary>
406 /// The name of the parameter (same as the ParameterInfo's name).
407 /// </summary>
408 public abstract string Name { get; }
409 /// <summary>
410 /// The name of the database function's parameter.
411 /// </summary>
412 public abstract string MappedName { get; }
413 /// <summary>
414 /// The CLR type of the parameter.
415 /// </summary>
416 public abstract Type ParameterType { get; }
417 /// <summary>
418 /// The database type of the parameter.
419 /// </summary>
420 [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db", Justification = "Conforms to legacy spelling.")]
421 public abstract string DbType { get; }
424 /// <summary>
425 /// A MetaAssociation represents an association relationship between two entity types.
426 /// </summary>
427 public abstract class MetaAssociation {
428 /// <summary>
429 /// The type on the other end of the association.
430 /// </summary>
431 public abstract MetaType OtherType { get; }
432 /// <summary>
433 /// The member on this side that represents the association.
434 /// </summary>
435 public abstract MetaDataMember ThisMember { get; }
436 /// <summary>
437 /// The member on the other side of this association that represents the reverse association (may be null).
438 /// </summary>
439 public abstract MetaDataMember OtherMember { get; }
440 /// <summary>
441 /// A list of members representing the values on this side of the association.
442 /// </summary>
443 public abstract ReadOnlyCollection<MetaDataMember> ThisKey { get; }
444 /// <summary>
445 /// A list of members representing the values on the other side of the association.
446 /// </summary>
447 public abstract ReadOnlyCollection<MetaDataMember> OtherKey { get; }
448 /// <summary>
449 /// True if the association is OneToMany.
450 /// </summary>
451 public abstract bool IsMany { get; }
452 /// <summary>
453 /// True if the other type is the parent of this type.
454 /// </summary>
455 public abstract bool IsForeignKey { get; }
456 /// <summary>
457 /// True if the association is unique (defines a uniqueness constraint).
458 /// </summary>
459 public abstract bool IsUnique { get; }
460 /// <summary>
461 /// True if the association may be null (key values).
462 /// </summary>
463 public abstract bool IsNullable { get; }
464 /// <summary>
465 /// True if the ThisKey forms the identity (primary key) of the this type.
466 /// </summary>
467 public abstract bool ThisKeyIsPrimaryKey { get; }
468 /// <summary>
469 /// True if the OtherKey forms the identity (primary key) of the other type.
470 /// </summary>
471 public abstract bool OtherKeyIsPrimaryKey { get; }
472 /// <summary>
473 /// Specifies the behavior when the child is deleted (e.g. CASCADE, SET NULL).
474 /// Returns null if no action is specified on delete.
475 /// </summary>
476 public abstract string DeleteRule { get; }
477 /// <summary>
478 /// Specifies whether the object should be deleted when this association
479 /// is set to null.
480 /// </summary>
481 public abstract bool DeleteOnNull { get; }
484 /// <summary>
485 /// A MetaAccessor
486 /// </summary>
487 public abstract class MetaAccessor {
488 /// <summary>
489 /// The type of the member accessed by this accessor.
490 /// </summary>
491 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The contexts in which this is available are fairly specific.")]
492 public abstract Type Type { get; }
493 /// <summary>
494 /// Gets the value as an object.
495 /// </summary>
496 /// <param name="instance">The instance to get the value from.</param>
497 /// <returns>Value.</returns>
498 public abstract object GetBoxedValue(object instance);
499 /// <summary>
500 /// Sets the value as an object.
501 /// </summary>
502 /// <param name="instance">The instance to set the value into.</param>
503 /// <param name="value">The value to set.</param>
504 [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Microsoft: Needs to handle classes and structs.")]
505 [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", Justification="Unknown reason.")]
506 public abstract void SetBoxedValue(ref object instance, object value);
507 /// <summary>
508 /// True if the instance has a loaded or assigned value.
509 /// </summary>
510 public virtual bool HasValue(object instance) {
511 return true;
513 /// <summary>
514 /// True if the instance has an assigned value.
515 /// </summary>
516 public virtual bool HasAssignedValue(object instance) {
517 return true;
519 /// <summary>
520 /// True if the instance has a value loaded from a deferred source.
521 /// </summary>
522 public virtual bool HasLoadedValue(object instance) {
523 return false;
527 /// <summary>
528 /// A strongly-typed MetaAccessor. Used for reading from and writing to
529 /// CLR objects.
530 /// </summary>
531 /// <typeparam name="T">The type of the object</typeparam>
532 /// <typeparam name="V">The type of the accessed member</typeparam>
533 public abstract class MetaAccessor<TEntity, TMember> : MetaAccessor {
534 /// <summary>
535 /// The underlying CLR type.
536 /// </summary>
537 public override Type Type {
538 get { return typeof(TMember); }
540 /// <summary>
541 /// Set the boxed value on an instance.
542 /// </summary>
543 public override void SetBoxedValue(ref object instance, object value) {
544 TEntity tInst = (TEntity)instance;
545 this.SetValue(ref tInst, (TMember)value);
546 instance = tInst;
548 /// <summary>
549 /// Retrieve the boxed value.
550 /// </summary>
551 public override object GetBoxedValue(object instance) {
552 return this.GetValue((TEntity)instance);
554 /// <summary>
555 /// Gets the strongly-typed value.
556 /// </summary>
557 public abstract TMember GetValue(TEntity instance);
558 /// <summary>
559 /// Sets the strongly-typed value
560 /// </summary>
561 [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "0#", Justification = "Unknown reason.")]
562 public abstract void SetValue(ref TEntity instance, TMember value);