PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/referencesource/System.Data.Linq/Mapping/MetaModel.cs

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