PageRenderTime 31ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/src/FluentNHibernate/Mapping/CompositeIdentityPart.cs

https://github.com/dotnetchris/fluent-nhibernate
C# | 195 lines | 124 code | 33 blank | 38 comment | 5 complexity | 1ec606bac1a537d93df1496afa838350 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. using FluentNHibernate.Mapping.Providers;
  8. using FluentNHibernate.MappingModel;
  9. using FluentNHibernate.MappingModel.Identity;
  10. using FluentNHibernate.Utils;
  11. namespace FluentNHibernate.Mapping
  12. {
  13. public class CompositeIdentityPart<T> : ICompositeIdMappingProvider
  14. {
  15. private readonly AccessStrategyBuilder<CompositeIdentityPart<T>> access;
  16. private readonly AttributeStore<CompositeIdMapping> attributes = new AttributeStore<CompositeIdMapping>();
  17. private readonly IList<KeyPropertyMapping> keyProperties = new List<KeyPropertyMapping>();
  18. private readonly IList<KeyManyToOneMapping> keyManyToOnes = new List<KeyManyToOneMapping>();
  19. private bool nextBool = true;
  20. public CompositeIdentityPart()
  21. {
  22. access = new AccessStrategyBuilder<CompositeIdentityPart<T>>(this, value => attributes.Set(x => x.Access, value));
  23. }
  24. public CompositeIdentityPart(string name) : this()
  25. {
  26. attributes.Set(x => x.Name, name);
  27. }
  28. /// <summary>
  29. /// Defines a property to be used as a key for this composite-id.
  30. /// </summary>
  31. /// <param name="expression">A member access lambda expression for the property</param>
  32. /// <returns>The composite identity part fluent interface</returns>
  33. public CompositeIdentityPart<T> KeyProperty(Expression<Func<T, object>> expression)
  34. {
  35. var property = ReflectionHelper.GetProperty(expression).ToMember();
  36. return KeyProperty(property, property.Name, null);
  37. }
  38. /// <summary>
  39. /// Defines a property to be used as a key for this composite-id with an explicit column name.
  40. /// </summary>
  41. /// <param name="expression">A member access lambda expression for the property</param>
  42. /// <param name="columnName">The column name in the database to use for this key, or null to use the property name</param>
  43. /// <returns>The composite identity part fluent interface</returns>
  44. public CompositeIdentityPart<T> KeyProperty(Expression<Func<T, object>> expression, string columnName)
  45. {
  46. var property = ReflectionHelper.GetProperty(expression).ToMember();
  47. return KeyProperty(property, columnName, null);
  48. }
  49. /// <summary>
  50. /// Defines a property to be used as a key for this composite-id with an explicit column name.
  51. /// </summary>
  52. /// <param name="expression">A member access lambda expression for the property</param>
  53. /// <param name="keyPropertyAction">Additional settings for the key property</param>
  54. /// <returns>The composite identity part fluent interface</returns>
  55. public CompositeIdentityPart<T> KeyProperty(Expression<Func<T, object>> expression, Action<KeyPropertyPart> keyPropertyAction)
  56. {
  57. var property = ReflectionHelper.GetProperty(expression).ToMember();
  58. return KeyProperty(property, string.Empty, keyPropertyAction);
  59. }
  60. protected virtual CompositeIdentityPart<T> KeyProperty(Member property, string columnName, Action<KeyPropertyPart> customMapping)
  61. {
  62. var key = new KeyPropertyMapping
  63. {
  64. Name = property.Name,
  65. Type = new TypeReference(property.PropertyType),
  66. ContainingEntityType = typeof(T)
  67. };
  68. if (customMapping != null)
  69. {
  70. var part = new KeyPropertyPart(key);
  71. customMapping(part);
  72. }
  73. if(!string.IsNullOrEmpty(columnName))
  74. key.AddColumn(new ColumnMapping { Name = columnName });
  75. keyProperties.Add(key);
  76. return this;
  77. }
  78. /// <summary>
  79. /// Defines a reference to be used as a many-to-one key for this composite-id with an explicit column name.
  80. /// </summary>
  81. /// <param name="expression">A member access lambda expression for the property</param>
  82. /// <returns>The composite identity part fluent interface</returns>
  83. public CompositeIdentityPart<T> KeyReference(Expression<Func<T, object>> expression)
  84. {
  85. var property = ReflectionHelper.GetProperty(expression).ToMember();
  86. return KeyReference(property, property.Name, null);
  87. }
  88. /// <summary>
  89. /// Defines a reference to be used as a many-to-one key for this composite-id with an explicit column name.
  90. /// </summary>
  91. /// <param name="expression">A member access lambda expression for the property</param>
  92. /// <param name="columnName">The column name in the database to use for this key, or null to use the property name</param>
  93. /// <returns>The composite identity part fluent interface</returns>
  94. public CompositeIdentityPart<T> KeyReference(Expression<Func<T, object>> expression, string columnName)
  95. {
  96. var property = ReflectionHelper.GetProperty(expression).ToMember();
  97. return KeyReference(property, columnName, null);
  98. }
  99. /// <summary>
  100. /// Defines a reference to be used as a many-to-one key for this composite-id with an explicit column name.
  101. /// </summary>
  102. /// <param name="expression">A member access lambda expression for the property</param>
  103. /// <param name="columnName">The column name in the database to use for this key, or null to use the property name</param>
  104. /// <param name="customMapping">A lambda expression specifying additional settings for the key reference</param>
  105. /// <returns>The composite identity part fluent interface</returns>
  106. public CompositeIdentityPart<T> KeyReference(Expression<Func<T, object>> expression, string columnName, Action<KeyManyToOnePart> customMapping)
  107. {
  108. var property = ReflectionHelper.GetProperty(expression).ToMember();
  109. return KeyReference(property, columnName, customMapping);
  110. }
  111. protected virtual CompositeIdentityPart<T> KeyReference(Member property, string columnName, Action<KeyManyToOnePart> customMapping)
  112. {
  113. var key = new KeyManyToOneMapping
  114. {
  115. Name = property.Name,
  116. Class = new TypeReference(property.PropertyType),
  117. ContainingEntityType = typeof(T)
  118. };
  119. key.AddColumn(new ColumnMapping { Name = columnName });
  120. var keyPart = new KeyManyToOnePart(key);
  121. if (customMapping != null)
  122. customMapping(keyPart);
  123. keyManyToOnes.Add(key);
  124. return this;
  125. }
  126. /// <summary>
  127. /// Set the access and naming strategy for this identity.
  128. /// </summary>
  129. public AccessStrategyBuilder<CompositeIdentityPart<T>> Access
  130. {
  131. get { return access; }
  132. }
  133. [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  134. public CompositeIdentityPart<T> Not
  135. {
  136. get
  137. {
  138. nextBool = false;
  139. return this;
  140. }
  141. }
  142. public CompositeIdentityPart<T> Mapped()
  143. {
  144. attributes.Set(x => x.Mapped, nextBool);
  145. nextBool = true;
  146. return this;
  147. }
  148. public CompositeIdentityPart<T> UnsavedValue(string value)
  149. {
  150. attributes.Set(x => x.UnsavedValue, value);
  151. return this;
  152. }
  153. CompositeIdMapping ICompositeIdMappingProvider.GetCompositeIdMapping()
  154. {
  155. var mapping = new CompositeIdMapping(attributes.CloneInner());
  156. mapping.ContainingEntityType = typeof(T);
  157. keyProperties.Each(mapping.AddKeyProperty);
  158. keyManyToOnes.Each(mapping.AddKeyManyToOne);
  159. return mapping;
  160. }
  161. }
  162. }