Mercurial > pub > bltoolkit
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 } |
