/src/Framework/N2/Persistence/NH/NHExtensions.cs

https://github.com/lundbeck/n2cms · C# · 156 lines · 137 code · 19 blank · 0 comment · 30 complexity · 22511291bcc0a1c30e906dcdcff024bf MD5 · raw file

  1. using N2.Details;
  2. using NHibernate;
  3. using NHibernate.Criterion;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. namespace N2.Persistence.NH
  10. {
  11. internal static class NHExtensions
  12. {
  13. public static ICriteria CreateCriteria<TEntity>(this ISession session, IParameter parameter)
  14. {
  15. var expr = parameter.CreateCriterion();
  16. var crit = RepositoryHelper<TEntity>.CreateCriteriaFromArray(session, new[] { expr });
  17. var pc = parameter as ParameterCollection;
  18. if (pc != null)
  19. {
  20. if (pc.Order != null)
  21. {
  22. crit.AddOrder(new NHibernate.Criterion.Order(pc.Order.Property, !pc.Order.Descending));
  23. }
  24. if (pc.Range != null)
  25. {
  26. if (pc.Range.Skip > 0)
  27. crit.SetFirstResult(pc.Range.Skip);
  28. if (pc.Range.Take > 0)
  29. crit.SetMaxResults(pc.Range.Take);
  30. }
  31. }
  32. return crit;
  33. }
  34. public static NHibernate.Criterion.ICriterion CreateCriterion(this IParameter parameter)
  35. {
  36. if (parameter is Parameter)
  37. {
  38. var p = parameter as Parameter;
  39. if (p != null && p.IsDetail)
  40. return CreateDetailExpression(p);
  41. return CreateExpression(p.Name, p.Value, p.Comparison, false);
  42. }
  43. else if (parameter is ParameterCollection)
  44. {
  45. var pc = parameter as ParameterCollection;
  46. var x = pc.Operator == Operator.And
  47. ? (Junction)Expression.Conjunction()
  48. : (Junction)Expression.Disjunction();
  49. foreach (var p in pc)
  50. x.Add(CreateCriterion(p));
  51. return x;
  52. }
  53. throw new NotImplementedException();
  54. }
  55. private static ICriterion CreateDetailExpression(Parameter p)
  56. {
  57. if (p.Comparison == Comparison.NotNull)
  58. return Subqueries.PropertyIn("ID",
  59. DetachedCriteria.For<ContentDetail>()
  60. .SetProjection(Projections.Property("EnclosingItem.ID"))
  61. .Add(Expression.Eq("Name", p.Name)));
  62. if (p.Comparison == Comparison.Null)
  63. return Subqueries.PropertyNotIn("ID",
  64. DetachedCriteria.For<ContentDetail>()
  65. .SetProjection(Projections.Property("EnclosingItem.ID"))
  66. .Add(Expression.Eq("Name", p.Name)));
  67. string propertyName = p.Comparison.HasFlag(Comparison.In)
  68. ? ContentDetail.GetAssociatedEnumerablePropertyName(p.Value as IEnumerable)
  69. : ContentDetail.GetAssociatedPropertyName(p.Value);
  70. var subselect = DetachedCriteria.For<ContentDetail>()
  71. .SetProjection(Projections.Property("EnclosingItem.ID"))
  72. .Add(CreateExpression(propertyName, ContentDetail.ExtractQueryValue(p.Value), p.Comparison, true));
  73. if (p.Name != null)
  74. subselect = subselect.Add(Expression.Eq("Name", p.Name));
  75. return Subqueries.PropertyIn("ID", subselect);
  76. }
  77. private static ICriterion CreateExpression(string propertyName, object value, Comparison comparisonType, bool isDetail)
  78. {
  79. if (value == null)
  80. return Expression.IsNull(propertyName);
  81. if (propertyName == "LinkedItem")
  82. {
  83. propertyName = "LinkedItem.ID";
  84. value = Utility.GetProperty(value, "ID");
  85. }
  86. switch (comparisonType)
  87. {
  88. case Comparison.Equal:
  89. return Expression.Eq(propertyName, value);
  90. case Comparison.GreaterOrEqual:
  91. return Expression.Ge(propertyName, value);
  92. case Comparison.GreaterThan:
  93. return Expression.Gt(propertyName, value);
  94. case Comparison.LessOrEqual:
  95. return Expression.Le(propertyName, value);
  96. case Comparison.LessThan:
  97. return Expression.Lt(propertyName, value);
  98. case Comparison.Like:
  99. return Expression.Like(propertyName, value);
  100. case Comparison.NotEqual:
  101. return Expression.Not(Expression.Eq(propertyName, value));
  102. case Comparison.NotLike:
  103. return Expression.Not(Expression.Like(propertyName, value));
  104. case Comparison.NotNull:
  105. return Expression.IsNotNull(propertyName);
  106. case Comparison.Null:
  107. return Expression.IsNull(propertyName);
  108. case Comparison.In:
  109. return Expression.In(propertyName, ((IEnumerable)value).OfType<object>().ToArray());
  110. case Comparison.NotIn:
  111. return Expression.Not(Expression.In(propertyName, ((IEnumerable)value).OfType<object>().ToArray()));
  112. }
  113. if (value is string)
  114. return Expression.Like(propertyName, value);
  115. return Expression.Eq(propertyName, value);
  116. }
  117. public static IEnumerable<IDictionary<string, object>> SelectProperties(this ICriteria crit, string[] properties)
  118. {
  119. var projection = Projections.ProjectionList();
  120. foreach (var property in properties)
  121. projection.Add(Projections.Property(property));
  122. if (properties.Length == 1)
  123. return crit.SetProjection(projection)
  124. .List<object>()
  125. .Select(col => new Dictionary<string, object>() { { properties[0], col } });
  126. return crit.SetProjection(projection)
  127. .List<System.Collections.IList>()
  128. .Select(l =>
  129. {
  130. var row = new Dictionary<string, object>();
  131. for (int i = 0; i < properties.Length; i++)
  132. row[properties[i]] = l[i];
  133. return row;
  134. });
  135. }
  136. }
  137. }