Mercurial > pub > bltoolkit
comparison Source/ServiceModel/LinqService.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.Globalization; | |
4 using System.Linq; | |
5 using System.ServiceModel; | |
6 using System.Web.Services; | |
7 | |
8 namespace BLToolkit.ServiceModel | |
9 { | |
10 using Data; | |
11 using Data.Linq; | |
12 using Data.Sql; | |
13 | |
14 [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] | |
15 [WebService (Namespace = "http://tempuri.org/")] | |
16 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] | |
17 public class LinqService : ILinqService | |
18 { | |
19 public LinqService() | |
20 { | |
21 } | |
22 | |
23 public LinqService(string configuration) | |
24 { | |
25 Configuration = configuration; | |
26 } | |
27 | |
28 public string Configuration { get; set; } | |
29 public bool AllowUpdates { get; set; } | |
30 | |
31 public static Func<string,Type> TypeResolver = _ => null; | |
32 | |
33 public virtual IDataContext CreateDataContext() | |
34 { | |
35 return Settings.CreateDefaultDataContext(Configuration); | |
36 } | |
37 | |
38 protected virtual void ValidateQuery(LinqServiceQuery query) | |
39 { | |
40 if (AllowUpdates == false && !query.Query.IsSelect) | |
41 throw new LinqException("Insert/Update/Delete requests are not allowed by the service policy."); | |
42 } | |
43 | |
44 protected virtual void HandleException(Exception exception) | |
45 { | |
46 } | |
47 | |
48 #region ILinqService Members | |
49 | |
50 public Type SqlProviderType { get; set; } | |
51 | |
52 [WebMethod] | |
53 public virtual string GetSqlProviderType() | |
54 { | |
55 try | |
56 { | |
57 if (SqlProviderType == null) | |
58 using (var ctx = CreateDataContext()) | |
59 SqlProviderType = ctx.CreateSqlProvider().GetType(); | |
60 | |
61 return SqlProviderType.FullName; | |
62 } | |
63 catch (Exception exception) | |
64 { | |
65 HandleException(exception); | |
66 throw; | |
67 } | |
68 } | |
69 | |
70 class QueryContext : IQueryContext | |
71 { | |
72 public SqlQuery SqlQuery { get; set; } | |
73 public object Context { get; set; } | |
74 public SqlParameter[] Parameters { get; set; } | |
75 | |
76 public SqlParameter[] GetParameters() | |
77 { | |
78 return Parameters; | |
79 } | |
80 } | |
81 | |
82 [WebMethod] | |
83 public int ExecuteNonQuery(string queryData) | |
84 { | |
85 try | |
86 { | |
87 var query = LinqServiceSerializer.Deserialize(queryData); | |
88 | |
89 ValidateQuery(query); | |
90 | |
91 using (var db = CreateDataContext()) | |
92 { | |
93 var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); | |
94 return db.ExecuteNonQuery(obj); | |
95 } | |
96 } | |
97 catch (Exception exception) | |
98 { | |
99 HandleException(exception); | |
100 throw; | |
101 } | |
102 } | |
103 | |
104 [WebMethod] | |
105 public object ExecuteScalar(string queryData) | |
106 { | |
107 try | |
108 { | |
109 var query = LinqServiceSerializer.Deserialize(queryData); | |
110 | |
111 ValidateQuery(query); | |
112 | |
113 using (var db = CreateDataContext()) | |
114 { | |
115 var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); | |
116 return db.ExecuteScalar(obj); | |
117 } | |
118 } | |
119 catch (Exception exception) | |
120 { | |
121 HandleException(exception); | |
122 throw; | |
123 } | |
124 } | |
125 | |
126 [WebMethod] | |
127 public string ExecuteReader(string queryData) | |
128 { | |
129 try | |
130 { | |
131 var query = LinqServiceSerializer.Deserialize(queryData); | |
132 | |
133 ValidateQuery(query); | |
134 | |
135 using (var db = CreateDataContext()) | |
136 { | |
137 var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); | |
138 | |
139 using (var rd = db.ExecuteReader(obj)) | |
140 { | |
141 var ret = new LinqServiceResult | |
142 { | |
143 QueryID = Guid.NewGuid(), | |
144 FieldCount = rd.FieldCount, | |
145 FieldNames = new string[rd.FieldCount], | |
146 FieldTypes = new Type [rd.FieldCount], | |
147 Data = new List<string[]>(), | |
148 }; | |
149 | |
150 for (var i = 0; i < ret.FieldCount; i++) | |
151 { | |
152 ret.FieldNames[i] = rd.GetName(i); | |
153 ret.FieldTypes[i] = rd.GetFieldType(i); | |
154 } | |
155 | |
156 var varyingTypes = new List<Type>(); | |
157 | |
158 while (rd.Read()) | |
159 { | |
160 var data = new string [rd.FieldCount]; | |
161 var codes = new TypeCode[rd.FieldCount]; | |
162 | |
163 for (var i = 0; i < ret.FieldCount; i++) | |
164 codes[i] = Type.GetTypeCode(ret.FieldTypes[i]); | |
165 | |
166 ret.RowCount++; | |
167 | |
168 for (var i = 0; i < ret.FieldCount; i++) | |
169 { | |
170 if (!rd.IsDBNull(i)) | |
171 { | |
172 var code = codes[i]; | |
173 var type = rd.GetFieldType(i); | |
174 var idx = -1; | |
175 | |
176 if (type != ret.FieldTypes[i]) | |
177 { | |
178 code = Type.GetTypeCode(type); | |
179 idx = varyingTypes.IndexOf(type); | |
180 | |
181 if (idx < 0) | |
182 { | |
183 varyingTypes.Add(type); | |
184 idx = varyingTypes.Count - 1; | |
185 } | |
186 } | |
187 | |
188 switch (code) | |
189 { | |
190 case TypeCode.Decimal : data[i] = rd.GetDecimal (i).ToString(CultureInfo.InvariantCulture); break; | |
191 case TypeCode.Double : data[i] = rd.GetDouble (i).ToString(CultureInfo.InvariantCulture); break; | |
192 case TypeCode.Single : data[i] = rd.GetFloat (i).ToString(CultureInfo.InvariantCulture); break; | |
193 case TypeCode.DateTime : data[i] = rd.GetDateTime(i).ToString("o"); break; | |
194 default : | |
195 { | |
196 if (type == typeof(DateTimeOffset)) | |
197 { | |
198 var dt = rd.GetValue(i); | |
199 | |
200 if (dt is DateTime) | |
201 data[i] = ((DateTime)dt).ToString("o"); | |
202 else if (dt is DateTimeOffset) | |
203 data[i] = ((DateTimeOffset)dt).ToString("o"); | |
204 else | |
205 data[i] = rd.GetValue(i).ToString(); | |
206 } | |
207 else if (ret.FieldTypes[i] == typeof(byte[])) | |
208 data[i] = Convert.ToBase64String((byte[])rd.GetValue(i)); | |
209 else | |
210 data[i] = (rd.GetValue(i) ?? "").ToString(); | |
211 | |
212 break; | |
213 } | |
214 } | |
215 | |
216 if (idx >= 0) | |
217 data[i] = "\0" + (char)idx + data[i]; | |
218 } | |
219 } | |
220 | |
221 ret.Data.Add(data); | |
222 } | |
223 | |
224 ret.VaryingTypes = varyingTypes.ToArray(); | |
225 | |
226 return LinqServiceSerializer.Serialize(ret); | |
227 } | |
228 } | |
229 } | |
230 catch (Exception exception) | |
231 { | |
232 HandleException(exception); | |
233 throw; | |
234 } | |
235 } | |
236 | |
237 [WebMethod] | |
238 public int ExecuteBatch(string queryData) | |
239 { | |
240 try | |
241 { | |
242 var data = LinqServiceSerializer.DeserializeStringArray(queryData); | |
243 var queries = data.Select<string,LinqServiceQuery>(LinqServiceSerializer.Deserialize).ToArray(); | |
244 | |
245 foreach (var query in queries) | |
246 ValidateQuery(query); | |
247 | |
248 using (var db = CreateDataContext()) | |
249 { | |
250 if (db is DbManager) ((DbManager)db).BeginTransaction(); | |
251 | |
252 foreach (var query in queries) | |
253 { | |
254 var obj = db.SetQuery(new QueryContext { SqlQuery = query.Query, Parameters = query.Parameters }); | |
255 db.ExecuteNonQuery(obj); | |
256 } | |
257 | |
258 if (db is DbManager) ((DbManager)db).CommitTransaction(); | |
259 | |
260 return queryData.Length; | |
261 } | |
262 } | |
263 catch (Exception exception) | |
264 { | |
265 HandleException(exception); | |
266 throw; | |
267 } | |
268 } | |
269 | |
270 #endregion | |
271 } | |
272 } |