Advertisement
Veikedo

duper builder

Mar 23rd, 2018
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.56 KB | None | 0 0
  1. using System;
  2. using System.Linq.Expressions;
  3. using System.Reflection;
  4. using ETR.S7.Groups.AgentRequests.Core;
  5. using ETR.S7.Groups.AgentRequests.Domain;
  6. using ETR.S7.Groups.AgentRequests.Features.AgentRequests.Queries;
  7.  
  8. namespace ETR.S7.Groups.AgentRequests.Features
  9. {
  10.     internal class Client
  11.     {
  12.         public static void Test()
  13.         {
  14.             var filter = new GetAgentRequestsRegistry.Query();
  15.             var qb = new QueryBuilder<AgentRequest>();
  16.  
  17.             var query = qb
  18.                     .For(x => x.AddedDate)
  19.                     .LessThan(filter.AddedDateLessThan)
  20.                     .Between(filter.AddedDateGreaterThan, filter.AddedDateLessThan)
  21.                     .For(x => x.Title)
  22.                     .Contains(filter.Title)
  23.                     .Predicate
  24.                 ;
  25.         }
  26.     }
  27.  
  28.     public class QueryBuilder<TEntity>
  29.     {
  30.         public QueryBuilder()
  31.         {
  32.             Predicate = PredicateBuilder.True<TEntity>();
  33.         }
  34.  
  35.         public Expression<Func<TEntity, bool>> Predicate { get; private set; }
  36.  
  37.         public Member<TMember> For<TMember>(Expression<Func<TEntity, TMember>> destinationMember)
  38.         {
  39.             return new Member<TMember>(destinationMember, this);
  40.         }
  41.  
  42.         public class Member<TMember>
  43.         {
  44.             private readonly QueryBuilder<TEntity> _parent;
  45.  
  46.             public Member(Expression<Func<TEntity, TMember>> destinationMember, QueryBuilder<TEntity> parent)
  47.             {
  48.                 _parent = parent;
  49.                 DestinationMember = destinationMember;
  50.             }
  51.  
  52.             public Expression<Func<TEntity, bool>> Predicate => _parent.Predicate;
  53.  
  54.             public Expression<Func<TEntity, TMember>> DestinationMember { get; }
  55.  
  56.             public Member<TMember> And(Expression<Func<TEntity, bool>> expr2)
  57.             {
  58.                 _parent.Predicate = _parent.Predicate.And(expr2);
  59.                 return this;
  60.             }
  61.  
  62.             public Member<TNextMember> For<TNextMember>(Expression<Func<TEntity, TNextMember>> destinationMember)
  63.             {
  64.                 return _parent.For(destinationMember);
  65.             }
  66.         }
  67.     }
  68.  
  69.     public static class MemberQueryBuilderExtensions
  70.     {
  71.         private static readonly MethodInfo StringContainsMethod =
  72.             typeof(string).GetMethod(@"Contains", BindingFlags.Instance |
  73.                                                   BindingFlags.Public, null, new[] {typeof(string)}, null);
  74.  
  75.         public static QueryBuilder<TEntity>.Member<DateTimeOffset?> LessThan<TEntity>(
  76.             this QueryBuilder<TEntity>.Member<DateTimeOffset?> builder, DateTimeOffset? value)
  77.         {
  78.             if (value == null)
  79.             {
  80.                 return builder;
  81.             }
  82.  
  83.             var parameter = Expression.Parameter(typeof(TEntity));
  84.             var filterValueAccess = Expression.Constant(value, value.GetType());
  85.             var body = Expression.LessThan(builder.DestinationMember, filterValueAccess);
  86.             var result = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
  87.  
  88.             return builder.And(result);
  89.         }
  90.  
  91.         public static QueryBuilder<TEntity>.Member<DateTimeOffset?> LessThanOrEqual<TEntity>(
  92.             this QueryBuilder<TEntity>.Member<DateTimeOffset?> builder, DateTimeOffset? value)
  93.         {
  94.             if (value == null)
  95.             {
  96.                 return builder;
  97.             }
  98.  
  99.             var parameter = Expression.Parameter(typeof(TEntity));
  100.             var constant = Expression.Constant(value, value.GetType());
  101.             var body = Expression.LessThanOrEqual(builder.DestinationMember, constant);
  102.             var result = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
  103.  
  104.             return builder.And(result);
  105.         }
  106.  
  107.         public static QueryBuilder<TEntity>.Member<DateTimeOffset?> GreaterThanOrEqual<TEntity>(
  108.             this QueryBuilder<TEntity>.Member<DateTimeOffset?> builder, DateTimeOffset? value)
  109.         {
  110.             if (value == null)
  111.             {
  112.                 return builder;
  113.             }
  114.  
  115.             var parameter = Expression.Parameter(typeof(TEntity));
  116.             var constant = Expression.Constant(value, value.GetType());
  117.             var body = Expression.GreaterThanOrEqual(builder.DestinationMember, constant);
  118.             var result = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
  119.  
  120.             return builder.And(result);
  121.         }
  122.  
  123.         public static QueryBuilder<TEntity>.Member<string> Contains<TEntity>(
  124.             this QueryBuilder<TEntity>.Member<string> builder, string value)
  125.         {
  126.             if (value == null)
  127.             {
  128.                 return builder;
  129.             }
  130.  
  131.             var parameter = Expression.Parameter(typeof(TEntity));
  132.             var constant = Expression.Constant(value, value.GetType());
  133.             var body = Expression.Call(builder.DestinationMember, StringContainsMethod, constant);
  134.             ;
  135.             var result = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
  136.  
  137.             return builder.And(result);
  138.         }
  139.  
  140.         public static QueryBuilder<TEntity>.Member<DateTimeOffset?> Between<TEntity>(
  141.             this QueryBuilder<TEntity>.Member<DateTimeOffset?> builder, DateTimeOffset? min, DateTimeOffset? max)
  142.         {
  143.             if (max != null)
  144.             {
  145.                 builder.LessThanOrEqual(max);
  146.             }
  147.  
  148.             if (min != null)
  149.             {
  150.                 builder.GreaterThanOrEqual(min);
  151.             }
  152.  
  153.             return builder;
  154.         }
  155.     }
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement