comparison Source/Data/DbManager.Linq.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;
5 using System.Reflection;
6 using System.Text;
7
8 using BLToolkit.Aspects;
9
10 namespace BLToolkit.Data
11 {
12 using DataProvider;
13 using Linq;
14 using Sql;
15 using Sql.SqlProvider;
16
17 public partial class DbManager : IDataContext
18 {
19 public Table<T> GetTable<T>()
20 where T : class
21 {
22 return new Table<T>(this);
23 }
24
25 public Table<T> GetTable<T>(bool dispose)
26 where T : class
27 {
28 return new Table<T>(new DataContextInfo(this, dispose));
29 }
30
31 public Table<T> GetTable<T>(object instance, [NotNull]MethodInfo methodInfo, [NotNull] params object[] parameters)
32 where T : class
33 {
34 return Linq.Extensions.GetTable<T>(this, instance, methodInfo, parameters);
35 }
36
37 class PreparedQuery
38 {
39 public string[] Commands;
40 public List<SqlParameter> SqlParameters;
41 public IDbDataParameter[] Parameters;
42 public SqlQuery SqlQuery;
43 public ISqlProvider SqlProvider;
44 }
45
46 #region SetQuery
47
48 object IDataContext.SetQuery(IQueryContext queryContext)
49 {
50 var query = GetCommand(queryContext);
51
52 GetParameters(queryContext, query);
53
54 if (TraceSwitch.TraceInfo)
55 WriteTraceLine(((IDataContext)this).GetSqlText(query).Replace("\r", ""), TraceSwitch.DisplayName);
56
57 return query;
58 }
59
60 PreparedQuery GetCommand(IQueryContext query)
61 {
62 if (query.Context != null)
63 {
64 return new PreparedQuery
65 {
66 Commands = (string[])query.Context,
67 SqlParameters = query.SqlQuery.Parameters,
68 SqlQuery = query.SqlQuery
69 };
70 }
71
72 var sql = query.SqlQuery.ProcessParameters();
73
74 var newSql = ProcessQuery(sql);
75
76 if (sql != newSql)
77 {
78 sql = newSql;
79 sql.IsParameterDependent = true;
80 }
81
82 var sqlProvider = DataProvider.CreateSqlProvider();
83
84 var cc = sqlProvider.CommandCount(sql);
85 var sb = new StringBuilder();
86
87 var commands = new string[cc];
88
89 for (var i = 0; i < cc; i++)
90 {
91 sb.Length = 0;
92
93 sqlProvider.BuildSql(i, sql, sb, 0, 0, false);
94 commands[i] = sb.ToString();
95 }
96
97 if (!query.SqlQuery.IsParameterDependent)
98 query.Context = commands;
99
100 return new PreparedQuery
101 {
102 Commands = commands,
103 SqlParameters = sql.Parameters,
104 SqlQuery = sql,
105 SqlProvider = sqlProvider
106 };
107 }
108
109 protected virtual SqlQuery ProcessQuery(SqlQuery sqlQuery)
110 {
111 return sqlQuery;
112 }
113
114 void GetParameters(IQueryContext query, PreparedQuery pq)
115 {
116 var parameters = query.GetParameters();
117
118 if (parameters.Length == 0 && pq.SqlParameters.Count == 0)
119 return;
120
121 var x = DataProvider.Convert("x", ConvertType.NameToQueryParameter).ToString();
122 var y = DataProvider.Convert("y", ConvertType.NameToQueryParameter).ToString();
123
124 var parms = new List<IDbDataParameter>(x == y ? pq.SqlParameters.Count : parameters.Length);
125
126 if (x == y)
127 {
128 for (var i = 0; i < pq.SqlParameters.Count; i++)
129 {
130 var sqlp = pq.SqlParameters[i];
131
132 if (sqlp.IsQueryParameter)
133 {
134 var parm = parameters.Length > i && parameters[i] == sqlp ? parameters[i] : parameters.First(p => p == sqlp);
135 AddParameter(parms, x, parm);
136 }
137 }
138 }
139 else
140 {
141 foreach (var parm in parameters)
142 {
143 if (parm.IsQueryParameter && pq.SqlParameters.Contains(parm))
144 {
145 var name = DataProvider.Convert(parm.Name, ConvertType.NameToQueryParameter).ToString();
146 AddParameter(parms, name, parm);
147 }
148 }
149 }
150
151 pq.Parameters = parms.ToArray();
152 }
153
154 void AddParameter(ICollection<IDbDataParameter> parms, string name, SqlParameter parm)
155 {
156 var value = MappingSchema.ConvertParameterValue(parm.Value, parm.SystemType);
157
158 if (value != null)
159 {
160 if (parm.DbType == DbType.Object)
161 parms.Add(Parameter(name, value));
162 else if (parm.DbSize == 0)
163 parms.Add(Parameter(name, value, parm.DbType));
164 else
165 parms.Add(Parameter(name, value, parm.DbType, parm.DbSize));
166 }
167 else
168 {
169 var dataType = DataProvider.GetDbType(parm.SystemType);
170 if (parm.DbType != DbType.Object)
171 dataType = parm.DbType;
172 parms.Add(dataType == DbType.Object ? Parameter(name, value) : Parameter(name, null, dataType));
173 }
174 }
175
176 #endregion
177
178 #region ExecuteXXX
179
180 int IDataContext.ExecuteNonQuery(object query)
181 {
182 var pq = (PreparedQuery)query;
183
184 SetCommand(pq.Commands[0], pq.Parameters);
185
186 var now = default(DateTime);
187
188 if (TraceSwitch.TraceInfo)
189 now = DateTime.Now;
190
191 var n = ExecuteNonQuery();
192
193 if (TraceSwitch.TraceInfo)
194 WriteTraceLine(string.Format("Execution time: {0}. Records affected: {1}.\r\n", DateTime.Now - now, n), TraceSwitch.DisplayName);
195
196 return n;
197 }
198
199 object IDataContext.ExecuteScalar(object query)
200 {
201 var now = default(DateTime);
202
203 if (TraceSwitch.TraceInfo)
204 now = DateTime.Now;
205
206 var ret = ExecuteScalarInternal(query);
207
208 if (TraceSwitch.TraceInfo)
209 WriteTraceLine(string.Format("Execution time: {0}\r\n", DateTime.Now - now), TraceSwitch.DisplayName);
210
211 return ret;
212 }
213
214 object ExecuteScalarInternal(object query)
215 {
216 var pq = (PreparedQuery)query;
217
218 SetCommand(pq.Commands[0], pq.Parameters);
219
220 IDbDataParameter idparam = null;
221
222 if ((pq.SqlProvider ?? DataProvider.CreateSqlProvider()).IsIdentityParameterRequired)
223 {
224 var sql = pq.SqlQuery;
225
226 if (sql.IsInsert && sql.Insert.WithIdentity)
227 {
228 var pname = DataProvider.Convert("IDENTITY_PARAMETER", ConvertType.NameToQueryParameter).ToString();
229 idparam = OutputParameter(pname, DbType.Decimal);
230 DataProvider.AttachParameter(Command, idparam);
231 }
232 }
233
234 if (pq.Commands.Length == 1)
235 {
236 if (idparam != null)
237 {
238 ExecuteNonQuery(); // так сделано потому, что фаерберд провайдер не возвращает никаких параметров через ExecuteReader
239 // остальные провайдеры должны поддерживать такой режим
240 return idparam.Value;
241 }
242
243 return ExecuteScalar();
244 }
245
246 ExecuteNonQuery();
247
248 return SetCommand(pq.Commands[1]).ExecuteScalar();
249 }
250
251 IDataReader IDataContext.ExecuteReader(object query)
252 {
253 var pq = (PreparedQuery)query;
254
255 SetCommand(pq.Commands[0], pq.Parameters);
256
257 var now = default(DateTime);
258
259 if (TraceSwitch.TraceInfo)
260 now = DateTime.Now;
261
262 var ret = ExecuteReader();
263
264 if (TraceSwitch.TraceInfo)
265 WriteTraceLine(string.Format("Execution time: {0}\r\n", DateTime.Now - now), TraceSwitch.DisplayName);
266
267 return ret;
268 }
269
270 void IDataContext.ReleaseQuery(object query)
271 {
272 }
273
274 #endregion
275
276 #region GetSqlText
277
278 string IDataContext.GetSqlText(object query)
279 {
280 var pq = (PreparedQuery)query;
281
282 var sqlProvider = pq.SqlProvider ?? DataProvider.CreateSqlProvider();
283
284 var sb = new StringBuilder();
285
286 sb.Append("-- ").Append(ConfigurationString);
287
288 if (ConfigurationString != DataProvider.Name)
289 sb.Append(' ').Append(DataProvider.Name);
290
291 if (DataProvider.Name != sqlProvider.Name)
292 sb.Append(' ').Append(sqlProvider.Name);
293
294 sb.AppendLine();
295
296 if (pq.Parameters != null && pq.Parameters.Length > 0)
297 {
298 foreach (var p in pq.Parameters)
299 sb
300 .Append("-- DECLARE ")
301 .Append(p.ParameterName)
302 .Append(' ')
303 .Append(p.Value == null ? p.DbType.ToString() : p.Value.GetType().Name)
304 .AppendLine();
305
306 sb.AppendLine();
307
308 foreach (var p in pq.Parameters)
309 {
310 var value = p.Value;
311
312 if (value is string || value is char)
313 value = "'" + value.ToString().Replace("'", "''") + "'";
314
315 sb
316 .Append("-- SET ")
317 .Append(p.ParameterName)
318 .Append(" = ")
319 .Append(value)
320 .AppendLine();
321 }
322
323 sb.AppendLine();
324 }
325
326 foreach (var command in pq.Commands)
327 sb.AppendLine(command);
328
329 while (sb[sb.Length - 1] == '\n' || sb[sb.Length - 1] == '\r')
330 sb.Length--;
331
332 sb.AppendLine();
333
334 return sb.ToString();
335 }
336
337 #endregion
338
339 #region IDataContext Members
340
341 IDataContext IDataContext.Clone(bool forNestedQuery)
342 {
343 if (forNestedQuery && _connection != null && IsMarsEnabled)
344 return new DbManager(_dataProvider, _connection) { _mappingSchema = _mappingSchema, _transaction = _transaction };
345
346 return Clone();
347 }
348
349 string IDataContext.ContextID
350 {
351 get { return DataProvider.Name; }
352 }
353
354 static Func<ISqlProvider> GetCreateSqlProvider(DataProviderBase dp)
355 {
356 return dp.CreateSqlProvider;
357 }
358
359 Func<ISqlProvider> IDataContext.CreateSqlProvider
360 {
361 get { return GetCreateSqlProvider(DataProvider); }
362 }
363
364 #endregion
365 }
366 }