PageRenderTime 61ms CodeModel.GetById 38ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FluentNHibernate/Mapping/AnyPart.cs

https://github.com/dotnetchris/fluent-nhibernate
C# | 174 lines | 140 code | 24 blank | 10 comment | 8 complexity | 22b5173b71a30243f3c5dbd23bd3d658 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.Utils;
  10. namespace FluentNHibernate.Mapping
  11. {
  12. /// <summary>
  13. /// Represents the "Any" mapping in NHibernate. It is impossible to specify a foreign key constraint for this kind of association. For more information
  14. /// please reference chapter 5.2.4 in the NHibernate online documentation
  15. /// </summary>
  16. public class AnyPart<T> : IAnyMappingProvider
  17. {
  18. private readonly AttributeStore<AnyMapping> attributes = new AttributeStore<AnyMapping>();
  19. private readonly Type entity;
  20. private readonly Member property;
  21. private readonly AccessStrategyBuilder<AnyPart<T>> access;
  22. private readonly CascadeExpression<AnyPart<T>> cascade;
  23. private readonly IList<string> typeColumns = new List<string>();
  24. private readonly IList<string> identifierColumns = new List<string>();
  25. private readonly IList<MetaValueMapping> metaValues = new List<MetaValueMapping>();
  26. private bool nextBool = true;
  27. public AnyPart(Type entity, Member property)
  28. {
  29. this.entity = entity;
  30. this.property = property;
  31. access = new AccessStrategyBuilder<AnyPart<T>>(this, value => attributes.Set(x => x.Access, value));
  32. cascade = new CascadeExpression<AnyPart<T>>(this, value => attributes.Set(x => x.Cascade, value));
  33. }
  34. /// <summary>
  35. /// Defines how NHibernate will access the object for persisting/hydrating (Defaults to Property)
  36. /// </summary>
  37. public AccessStrategyBuilder<AnyPart<T>> Access
  38. {
  39. get { return access; }
  40. }
  41. /// <summary>
  42. /// Cascade style (Defaults to none)
  43. /// </summary>
  44. public CascadeExpression<AnyPart<T>> Cascade
  45. {
  46. get { return cascade; }
  47. }
  48. public AnyPart<T> IdentityType(Expression<Func<T, object>> expression)
  49. {
  50. return IdentityType(ReflectionHelper.GetProperty(expression).ToMember().PropertyType);
  51. }
  52. public AnyPart<T> IdentityType<TIdentity>()
  53. {
  54. return IdentityType(typeof(TIdentity));
  55. }
  56. public AnyPart<T> IdentityType(Type type)
  57. {
  58. attributes.Set(x => x.IdType, type.AssemblyQualifiedName);
  59. return this;
  60. }
  61. public AnyPart<T> EntityTypeColumn(string columnName)
  62. {
  63. typeColumns.Add(columnName);
  64. return this;
  65. }
  66. public AnyPart<T> EntityIdentifierColumn(string columnName)
  67. {
  68. identifierColumns.Add(columnName);
  69. return this;
  70. }
  71. public AnyPart<T> AddMetaValue<TModel>(string valueMap)
  72. {
  73. metaValues.Add(new MetaValueMapping
  74. {
  75. Class = new TypeReference(typeof(TModel)),
  76. Value = valueMap,
  77. ContainingEntityType = entity
  78. });
  79. return this;
  80. }
  81. public AnyPart<T> Insert()
  82. {
  83. attributes.Set(x => x.Insert, nextBool);
  84. nextBool = true;
  85. return this;
  86. }
  87. public AnyPart<T> Update()
  88. {
  89. attributes.Set(x => x.Update, nextBool);
  90. nextBool = true;
  91. return this;
  92. }
  93. public AnyPart<T> ReadOnly()
  94. {
  95. attributes.Set(x => x.Insert, !nextBool);
  96. attributes.Set(x => x.Update, !nextBool);
  97. nextBool = true;
  98. return this;
  99. }
  100. public AnyPart<T> LazyLoad()
  101. {
  102. attributes.Set(x => x.Lazy, nextBool);
  103. nextBool = true;
  104. return this;
  105. }
  106. public AnyPart<T> OptimisticLock()
  107. {
  108. attributes.Set(x => x.OptimisticLock, nextBool);
  109. nextBool = true;
  110. return this;
  111. }
  112. [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  113. public AnyPart<T> Not
  114. {
  115. get
  116. {
  117. nextBool = !nextBool;
  118. return this;
  119. }
  120. }
  121. AnyMapping IAnyMappingProvider.GetAnyMapping()
  122. {
  123. var mapping = new AnyMapping(attributes.CloneInner());
  124. if (typeColumns.Count() == 0)
  125. throw new InvalidOperationException("<any> mapping is not valid without specifying an Entity Type Column");
  126. if (identifierColumns.Count() == 0)
  127. throw new InvalidOperationException("<any> mapping is not valid without specifying an Entity Identifier Column");
  128. if (!mapping.IsSpecified("IdType"))
  129. throw new InvalidOperationException("<any> mapping is not valid without specifying an IdType");
  130. mapping.ContainingEntityType = entity;
  131. if (!mapping.IsSpecified("Name"))
  132. mapping.Name = property.Name;
  133. if (!mapping.IsSpecified("MetaType"))
  134. {
  135. if (metaValues.Count() > 0)
  136. {
  137. metaValues.Each(mapping.AddMetaValue);
  138. mapping.MetaType = new TypeReference(typeof(string));
  139. }
  140. else
  141. mapping.MetaType = new TypeReference(property.PropertyType);
  142. }
  143. foreach (var column in typeColumns)
  144. mapping.AddTypeColumn(new ColumnMapping { Name = column });
  145. foreach (var column in identifierColumns)
  146. mapping.AddIdentifierColumn(new ColumnMapping { Name = column });
  147. return mapping;
  148. }
  149. }
  150. }