comparison Source/Data/Linq/Builder/OrderByBuilder.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
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 }