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