Mercurial > pub > bltoolkit
comparison Source/ServiceModel/RemoteDataContextBase.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.Data; | |
4 using System.Linq.Expressions; | |
5 using System.Text; | |
6 | |
7 namespace BLToolkit.ServiceModel | |
8 { | |
9 using Data.Linq; | |
10 using Data.Sql.SqlProvider; | |
11 using Mapping; | |
12 | |
13 public abstract class RemoteDataContextBase : IDataContext | |
14 { | |
15 protected abstract ILinqService GetClient(); | |
16 protected abstract IDataContext Clone (); | |
17 protected abstract string ContextIDPrefix { get; } | |
18 | |
19 string _contextID; | |
20 string IDataContext.ContextID | |
21 { | |
22 get { return _contextID ?? (_contextID = ContextIDPrefix + SqlProviderType.Name.Replace("SqlProvider", "")); } | |
23 } | |
24 | |
25 private MappingSchema _mappingSchema; | |
26 public MappingSchema MappingSchema | |
27 { | |
28 get | |
29 { | |
30 if (_mappingSchema == null) | |
31 { | |
32 var sp = ((IDataContext)this).CreateSqlProvider(); | |
33 _mappingSchema = sp is IMappingSchemaProvider ? ((IMappingSchemaProvider)sp).MappingSchema : Map.DefaultSchema; | |
34 } | |
35 | |
36 return _mappingSchema; | |
37 } | |
38 | |
39 set { _mappingSchema = value; } | |
40 } | |
41 | |
42 private Type _sqlProviderType; | |
43 public virtual Type SqlProviderType | |
44 { | |
45 get | |
46 { | |
47 if (_sqlProviderType == null) | |
48 { | |
49 var client = GetClient(); | |
50 | |
51 try | |
52 { | |
53 var type = client.GetSqlProviderType(); | |
54 _sqlProviderType = Type.GetType(type); | |
55 } | |
56 finally | |
57 { | |
58 ((IDisposable)client).Dispose(); | |
59 } | |
60 } | |
61 | |
62 return _sqlProviderType; | |
63 } | |
64 | |
65 set { _sqlProviderType = value; } | |
66 } | |
67 | |
68 public bool IsMarsEnabled | |
69 { | |
70 get { return false; } | |
71 } | |
72 | |
73 static readonly Dictionary<Type,Func<ISqlProvider>> _sqlProviders = new Dictionary<Type, Func<ISqlProvider>>(); | |
74 | |
75 Func<ISqlProvider> _createSqlProvider; | |
76 | |
77 Func<ISqlProvider> IDataContext.CreateSqlProvider | |
78 { | |
79 get | |
80 { | |
81 if (_createSqlProvider == null) | |
82 { | |
83 var type = SqlProviderType; | |
84 | |
85 if (!_sqlProviders.TryGetValue(type, out _createSqlProvider)) | |
86 lock (_sqlProviderType) | |
87 if (!_sqlProviders.TryGetValue(type, out _createSqlProvider)) | |
88 _sqlProviders.Add(type, _createSqlProvider = Expression.Lambda<Func<ISqlProvider>>(Expression.New(type)).Compile()); | |
89 } | |
90 | |
91 return _createSqlProvider; | |
92 } | |
93 } | |
94 | |
95 List<string> _queryBatch; | |
96 int _batchCounter; | |
97 | |
98 public void BeginBatch() | |
99 { | |
100 _batchCounter++; | |
101 | |
102 if (_queryBatch == null) | |
103 _queryBatch = new List<string>(); | |
104 } | |
105 | |
106 public void CommitBatch() | |
107 { | |
108 if (_batchCounter == 0) | |
109 throw new InvalidOperationException(); | |
110 | |
111 _batchCounter--; | |
112 | |
113 if (_batchCounter == 0) | |
114 { | |
115 var client = GetClient(); | |
116 | |
117 try | |
118 { | |
119 var data = LinqServiceSerializer.Serialize(_queryBatch.ToArray()); | |
120 client.ExecuteBatch(data); | |
121 } | |
122 finally | |
123 { | |
124 ((IDisposable)client).Dispose(); | |
125 _queryBatch = null; | |
126 } | |
127 } | |
128 } | |
129 | |
130 class QueryContext | |
131 { | |
132 public IQueryContext Query; | |
133 public ILinqService Client; | |
134 } | |
135 | |
136 object IDataContext.SetQuery(IQueryContext queryContext) | |
137 { | |
138 return new QueryContext { Query = queryContext }; | |
139 } | |
140 | |
141 int IDataContext.ExecuteNonQuery(object query) | |
142 { | |
143 var ctx = (QueryContext)query; | |
144 var q = ctx.Query.SqlQuery.ProcessParameters(); | |
145 var data = LinqServiceSerializer.Serialize(q, q.IsParameterDependent ? q.Parameters.ToArray() : ctx.Query.GetParameters()); | |
146 | |
147 if (_batchCounter > 0) | |
148 { | |
149 _queryBatch.Add(data); | |
150 return -1; | |
151 } | |
152 | |
153 ctx.Client = GetClient(); | |
154 | |
155 return ctx.Client.ExecuteNonQuery(data); | |
156 } | |
157 | |
158 object IDataContext.ExecuteScalar(object query) | |
159 { | |
160 if (_batchCounter > 0) | |
161 throw new LinqException("Incompatible batch operation."); | |
162 | |
163 var ctx = (QueryContext)query; | |
164 | |
165 ctx.Client = GetClient(); | |
166 | |
167 var q = ctx.Query.SqlQuery.ProcessParameters(); | |
168 | |
169 return ctx.Client.ExecuteScalar( | |
170 LinqServiceSerializer.Serialize(q, q.IsParameterDependent ? q.Parameters.ToArray() : ctx.Query.GetParameters())); | |
171 } | |
172 | |
173 IDataReader IDataContext.ExecuteReader(object query) | |
174 { | |
175 if (_batchCounter > 0) | |
176 throw new LinqException("Incompatible batch operation."); | |
177 | |
178 var ctx = (QueryContext)query; | |
179 | |
180 ctx.Client = GetClient(); | |
181 | |
182 var q = ctx.Query.SqlQuery.ProcessParameters(); | |
183 var ret = ctx.Client.ExecuteReader( | |
184 LinqServiceSerializer.Serialize(q, q.IsParameterDependent ? q.Parameters.ToArray() : ctx.Query.GetParameters())); | |
185 var result = LinqServiceSerializer.DeserializeResult(ret); | |
186 | |
187 return new ServiceModelDataReader(result); | |
188 } | |
189 | |
190 public void ReleaseQuery(object query) | |
191 { | |
192 var ctx = (QueryContext)query; | |
193 | |
194 if (ctx.Client != null) | |
195 ((IDisposable)ctx.Client).Dispose(); | |
196 } | |
197 | |
198 string IDataContext.GetSqlText(object query) | |
199 { | |
200 var ctx = (QueryContext)query; | |
201 var sqlProvider = ((IDataContext)this).CreateSqlProvider(); | |
202 var sb = new StringBuilder(); | |
203 | |
204 sb | |
205 .Append("-- ") | |
206 .Append("ServiceModel") | |
207 .Append(' ') | |
208 .Append(((IDataContext)this).ContextID) | |
209 .Append(' ') | |
210 .Append(sqlProvider.Name) | |
211 .AppendLine(); | |
212 | |
213 if (ctx.Query.SqlQuery.Parameters != null && ctx.Query.SqlQuery.Parameters.Count > 0) | |
214 { | |
215 foreach (var p in ctx.Query.SqlQuery.Parameters) | |
216 sb | |
217 .Append("-- DECLARE ") | |
218 .Append(p.Name) | |
219 .Append(' ') | |
220 .Append(p.Value == null ? p.SystemType.ToString() : p.Value.GetType().Name) | |
221 .AppendLine(); | |
222 | |
223 sb.AppendLine(); | |
224 | |
225 foreach (var p in ctx.Query.SqlQuery.Parameters) | |
226 { | |
227 var value = p.Value; | |
228 | |
229 if (value is string || value is char) | |
230 value = "'" + value.ToString().Replace("'", "''") + "'"; | |
231 | |
232 sb | |
233 .Append("-- SET ") | |
234 .Append(p.Name) | |
235 .Append(" = ") | |
236 .Append(value) | |
237 .AppendLine(); | |
238 } | |
239 | |
240 sb.AppendLine(); | |
241 } | |
242 | |
243 var cc = sqlProvider.CommandCount(ctx.Query.SqlQuery); | |
244 var commands = new string[cc]; | |
245 | |
246 for (var i = 0; i < cc; i++) | |
247 { | |
248 sb.Length = 0; | |
249 | |
250 sqlProvider.BuildSql(i, ctx.Query.SqlQuery, sb, 0, 0, false); | |
251 commands[i] = sb.ToString(); | |
252 } | |
253 | |
254 if (!ctx.Query.SqlQuery.IsParameterDependent) | |
255 ctx.Query.Context = commands; | |
256 | |
257 foreach (var command in commands) | |
258 sb.AppendLine(command); | |
259 | |
260 return sb.ToString(); | |
261 } | |
262 | |
263 IDataContext IDataContext.Clone(bool forNestedQuery) | |
264 { | |
265 return Clone(); | |
266 } | |
267 | |
268 public event EventHandler OnClosing; | |
269 | |
270 public void Dispose() | |
271 { | |
272 if (OnClosing != null) | |
273 OnClosing(this, EventArgs.Empty); | |
274 } | |
275 } | |
276 } |