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 }