annotate Source/Data/Linq/Builder/InsertOrUpdateBuilder.cs @ 9:1e85f66cf767 default tip

update bltoolkit
author nickolay
date Thu, 05 Apr 2018 20:53:26 +0300
parents f990fcb411a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Collections.Generic;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Linq.Expressions;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6 namespace BLToolkit.Data.Linq.Builder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8 using BLToolkit.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 using Data.Sql;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 class InsertOrUpdateBuilder : MethodCallBuilder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 #region InsertOrUpdateBuilder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 return methodCall.IsQueryable("InsertOrUpdate");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24 UpdateBuilder.BuildSetter(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 builder,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 buildInfo,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 (LambdaExpression)methodCall.Arguments[1].Unwrap(),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 sequence,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29 sequence.SqlQuery.Insert.Items,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 sequence);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 UpdateBuilder.BuildSetter(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 builder,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 buildInfo,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 (LambdaExpression)methodCall.Arguments[2].Unwrap(),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 sequence,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 sequence.SqlQuery.Update.Items,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38 sequence);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 sequence.SqlQuery.Update.Table = ((TableBuilder.TableContext)sequence).SqlTable;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42 sequence.SqlQuery.From.Tables.Clear();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 sequence.SqlQuery.From.Table(sequence.SqlQuery.Update.Table);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 if (methodCall.Arguments.Count == 3)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 var table = sequence.SqlQuery.Insert.Into;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 var keys = table.GetKeys(false);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 if (keys.Count == 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 throw new LinqException("InsertOrUpdate method requires the '{0}' table to have a primary key.", table.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53 var q =
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 (
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 from k in keys
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 join i in sequence.SqlQuery.Insert.Items on k equals i.Column
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 select new { k, i }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 ).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 var missedKey = keys.Except(q.Select(i => i.k)).FirstOrDefault();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 if (missedKey != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 throw new LinqException("InsertOrUpdate method requires the '{0}.{1}' field to be included in the insert setter.",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 table.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 ((SqlField)missedKey).Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67 sequence.SqlQuery.Update.Keys.AddRange(q.Select(i => i.i));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 UpdateBuilder.BuildSetter(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 builder,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 buildInfo,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 (LambdaExpression)methodCall.Arguments[3].Unwrap(),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 sequence,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 sequence.SqlQuery.Update.Keys,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 sequence);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 sequence.SqlQuery.QueryType = QueryType.InsertOrUpdate;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 return new InsertOrUpdateContext(buildInfo.Parent, sequence);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 protected override SequenceConvertInfo Convert(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 #region UpdateContext
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 class InsertOrUpdateContext : SequenceContextBase
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 public InsertOrUpdateContext(IBuildContext parent, IBuildContext sequence)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98 : base(parent, sequence, null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 public override void BuildQuery<T>(Query<T> query, ParameterExpression queryParameter)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 if (Builder.SqlProvider.IsInsertOrUpdateSupported)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105 query.SetNonQueryQuery();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 query.MakeAlternativeInsertOrUpdate(SqlQuery);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110 public override Expression BuildExpression(Expression expression, int level)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 public override SqlInfo[] ConvertToIndex(Expression expression, int level, ConvertFlags flags)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 public override IsExpressionResult IsExpression(Expression expression, int level, RequestFor requestFlag)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132 throw new InvalidOperationException();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 }