0
|
1 using System;
|
|
2 using System.Linq;
|
|
3 using System.Linq.Expressions;
|
|
4
|
|
5 namespace BLToolkit.Data.Linq.Builder
|
|
6 {
|
|
7 using BLToolkit.Linq;
|
|
8
|
|
9 class OrderByBuilder : MethodCallBuilder
|
|
10 {
|
|
11 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
|
|
12 {
|
|
13 if (!methodCall.IsQueryable("OrderBy", "OrderByDescending", "ThenBy", "ThenByDescending"))
|
|
14 return false;
|
|
15
|
|
16 var body = ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Body.Unwrap();
|
|
17
|
|
18 if (body.NodeType == ExpressionType.MemberInit)
|
|
19 {
|
|
20 var mi = (MemberInitExpression)body;
|
|
21 bool throwExpr;
|
|
22
|
|
23 if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0)
|
|
24 throwExpr = true;
|
|
25 else
|
|
26 throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment);
|
|
27
|
|
28 if (throwExpr)
|
|
29 throw new NotSupportedException(string.Format("Explicit construction of entity type '{0}' in order by is not allowed.", body.Type));
|
|
30 }
|
|
31
|
|
32 return true;
|
|
33 }
|
|
34
|
|
35 protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
|
|
36 {
|
|
37 var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
|
|
38
|
|
39 if (sequence.SqlQuery.Select.TakeValue != null || sequence.SqlQuery.Select.SkipValue != null)
|
|
40 sequence = new SubQueryContext(sequence);
|
|
41
|
|
42 var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap();
|
|
43 var sparent = sequence.Parent;
|
|
44 var order = new ExpressionContext(buildInfo.Parent, sequence, lambda);
|
|
45 var body = lambda.Body.Unwrap();
|
|
46 var sql = builder.ConvertExpressions(order, body, ConvertFlags.Key);
|
|
47
|
|
48 builder.ReplaceParent(order, sparent);
|
|
49
|
|
50 if (!methodCall.Method.Name.StartsWith("Then"))
|
|
51 sequence.SqlQuery.OrderBy.Items.Clear();
|
|
52
|
|
53 foreach (var expr in sql)
|
|
54 {
|
|
55 var e = builder.ConvertSearchCondition(sequence, expr.Sql);
|
|
56 sequence.SqlQuery.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending"));
|
|
57 }
|
|
58
|
|
59 return sequence;
|
|
60 }
|
|
61
|
|
62 protected override SequenceConvertInfo Convert(
|
|
63 ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
|
|
64 {
|
|
65 return null;
|
|
66 }
|
|
67 }
|
|
68 }
|