自定义个“微信约战斗地主棋牌开发缓存数据库”玩玩
2018-01-05 15:10
537 查看
前言:首先声明,此文题目算是标题党的一种,是本人为了完成与widows服务通信编程学习幻想出来的一个模型(并不是真的缓存数据库),并且会作为本人以后加深多线程、设计模式、非关系型数据库等方面学习的一个模型实例,毕竟有一个实际的模型更容易加深理解。
完成这部分模型,大概会做一下几件事情:
微信约战斗地主棋牌开发( h5.super-mans.com Q:2012035031)
1、 创建一个Windows服务(用来寄存这个“缓存数据库”)
2、 创建一个WCF服务,寄宿在windows服务中(用于跟客户端通信,对“缓存数据库”进行增删查操作)
3、 创建客户端进行测试
第1步:WCF服务的创建及对缓存对象增删查的实现
WCF服务创建的过程及其Endpoint节点相关基础在这里不作累述,网上很多资料,这里直接贴Contract及其实现的代码,保存表数据的数据结构是Dictionary<string,DataTable>,其中key存放是表名,DataTable存放是数据。
复制代码
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Data;
6
7 using System.Linq;
8
9 using System.Runtime.Serialization;
10
11 using System.ServiceModel;
12
13 using System.ServiceModel.Web;
14
15 using System
4000
.Text;
16
17
18
19 namespace SelfWcfService
20
21 {
22
23 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
24
25 [ServiceContract]
26
27 public interface ISelfSQLData
28
29 {
30
31 [OperationContract]
32
33 ExcuteResult CreateTable(string tableName, DataTable colNames);
34
35
36
37 [OperationContract]
38
39 ExcuteResult Insert(string tableName, SelfDataRow dr);
40
41
42
43 [OperationContract]
44
45 ExcuteResult Delete(string tableName, SelfDataRow dr);
46
47
48
49 [OperationContract]
50
51 ExcuteResult DropTable(string tableName);
52
53
54
55 [OperationContract]
56
57 Dictionary<string, DataTable> GetData();
58
59 }
60
61
62
63 [DataContract]
64
65 public class SQLData
66
67 {
68
69 [DataMember]
70
71 public Dictionary<string, DataTable> DataTables { get; set; }
72
73 }
74
75
76
77 [DataContract]
78
79 public class SelfDataRow
80
81 {
82
83 [DataMember]
84
85 public DataTable DataTable { get; set; }
86
87 }
88
89 }
复制代码
接口实现部分:
微信约战斗地主棋牌开发( h5.super-mans.com Q:2012035031)
复制代码
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Data;
6
7 using System.Linq;
8
9 using System.Runtime.Serialization;
10
11 using System.ServiceModel;
12
13 using System.ServiceModel.Web;
14
15 using System.Text;
16
17
18
19 namespace SelfWcfService
20
21 {
22
23 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
24
25 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
26
27 public class SelfSQLData : ISelfSQLData
28
29 {
30
31 private static SQLData _sqlData;
32
33 public static SQLData SqlData
34
35 {
36
37 get
38
39 {
40
41 if (_sqlData == null)
42
43 {
44
45 _sqlData = new SQLData();
46
47 }
48
49 if (_sqlData.DataTables == null)
50
51 {
52
53 _sqlData.DataTables = new Dictionary<string, System.Data.DataTable>();
54
55 }
56
57 return _sqlData;
58
59 }
60
61 set
62
63 {
64
65 _sqlData = value;
66
67 }
68
69 }
70
71
72
73 private void InitalSqlData()
74
75 {
76
77 if (_sqlData == null)
78
79 {
80
81 _sqlData = new SQLData();
82
83 }
84
85 if (_sqlData.DataTables == null)
86
87 {
88
89 _sqlData.DataTables = new Dictionary<string, System.Data.DataTable>();
90
91 }
92
93 }
94
95
96
97 public ExcuteResult CreateTable(string tableName, DataTable colNames)
98
99 {
100
101 if (string.IsNullOrWhiteSpace(tableName))
102
103 {
104
105 return new ExcuteResult(1, "表名不能为空!");
106
107 }
108
109 if (colNames == null || colNames.Columns.Count < 1)
110
111 {
112
113 return new ExcuteResult(1, "表字段不能为空!");
114
115 }
116
117 InitalSqlData();
118
119 if (!_sqlData.DataTables.ContainsKey(tableName))
120
121 {
122
123 try
124
125 {
126
127 _sqlData.DataTables.Add(tableName, colNames);
128
129 }
130
131 catch (Exception ex)
132
133 {
134
135 return new ExcuteResult(1, ex.Message);
136
137 }
138
139 return new ExcuteResult(0, "表" + tableName + "创建成功!");
140
141 }
142
143 else
144
145 {
146
147 return new ExcuteResult(1, "已存在名为'" + tableName + "'的表");
148
149 }
150
151 }
152
153
154
155 public ExcuteResult Insert(string tableName, SelfDataRow dr)
156
157 {
158
159 if (string.IsNullOrWhiteSpace(tableName))
160
161 {
162
163 return new ExcuteResult(1, "表名不能为空!");
164
165 }
166
167 if (dr == null)
168
169 {
170
171 return new ExcuteResult(1, "不能插入空的数据行!");
172
173 }
174
175 InitalSqlData();
176
177 if (!_sqlData.DataTables.ContainsKey(tableName))
178
179 {
180
181 try
182
183 {
184
185 _sqlData.DataTables[tableName].Rows.Add(dr.DataTable.Rows[0]);
186
187 }
188
189 catch (Exception ex)
190
191 {
192
193 return new ExcuteResult(1, ex.Message);
194
195 }
196
197 return new ExcuteResult(0, "数据新增成功!");
198
199 }
200
201 else
202
203 {
204
205 return new ExcuteResult(1, "表'" + tableName + "'不存在!");
206
207 }
208
209 }
210
211
212
213 public ExcuteResult Delete(string tableName, SelfDataRow dr)
214
215 {
216
217 if (string.IsNullOrWhiteSpace(tableName))
218
219 {
220
221 return new ExcuteResult(1, "表名不能为空!");
222
223 }
224
225 if (dr == null)
226
227 {
228
229 return new ExcuteResult(1, "请指定删除对象!");
230
231 }
232
233 InitalSqlData();
234
235 if (!_sqlData.DataTables.ContainsKey(tableName))
236
237 {
238
239 try
240
241 {
242
243 _sqlData.DataTables[tableName].Rows.Remove(dr.DataTable.Rows[0]);
244
245 }
246
247 catch (Exception ex)
248
249 {
250
251 return new ExcuteResult(1, ex.Message);
252
253 }
254
255 return new ExcuteResult(0, "数据删除成功!");
256
257 }
258
259 else
260
261 {
262
263 return new ExcuteResult(1, "表'" + tableName + "'不存在!");
264
265 }
266
267 }
268
269
270
271 public ExcuteResult DropTable(string tableName)
272
273 {
274
275 if (string.IsNullOrWhiteSpace(tableName))
276
277 {
278
279 return new ExcuteResult(1, "表名不能为空!");
280
281 }
282
283 InitalSqlData();
284
285 if (!_sqlData.DataTables.ContainsKey(tableName))
286
287 {
288
289 try
290
291 {
292
293 _sqlData.DataTables.Remove(tableName);
294
295 }
296
297 catch (Exception ex)
298
299 {
300
301 return new ExcuteResult(1, ex.Message);
302
303 }
304
305 return new ExcuteResult(0, "表" + tableName + "删除成功!");
306
307 }
308
309 else
310
311 {
312
313 return new ExcuteResult(1, "表'" + tableName + "'不存在!");
314
315 }
316
317 }
318
319
320
321 public Dictionary<string, DataTable> GetData()
322
323 {
324
325 return SqlData.DataTables;
326
327 }
328
329 }
330
331 }
复制代码
微信约战斗地主棋牌开发( h5.super-mans.com Q:2012035031)
整个WCF实现的逻辑都在上面了,web配置文件不需要改,因为它不以web的形式发布寄宿在IIS中,而是windows服务中。
第2步:将WCF寄宿在Windows服务中
Windows服务的创建、安装、启动在这里也不作累述,跟WCF一样,网上资料也很多。这里重点介绍一下将WCF寄宿在Windows服务中。
(1) 将wcf项目的dll引用到windows服务项目中
(2) 在app.config文件中配置WCF终结点
复制代码
1 <system.serviceModel>
2
3 <services>
4
5 <service behaviorConfiguration="BasicServiceBehavior"
6
7 name="SelfWcfService.SelfSQLData">
8
9 <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
10
11 contract="SelfWcfService.ISelfSQLData">
12
13 <!--<identity>
14
15 <dns value="192.168.1.4" />
16
17 </identity>-->
18
19 </endpoint>
20
21 <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
22
23 contract="IMetadataExchange" />
24
25 <host>
26
27 <baseAddresses>
28
29 <add baseAddress="net.tcp://localhost:9000/SelfSQLData.svc"/>
30
31 <add baseAddress="http://localhost:9001/SelfSQLData.svc"/>
32
33 </baseAddresses>
34
35 </host>
36
37 </service>
38
39 </services>
40
41 <behaviors>
42
43 <serviceBehaviors>
44
45 <behavior name="BasicServiceBehavior">
46
47 <serviceMetadata httpGetEnabled="true" />
48
49 <serviceDebug includeExceptionDetailInFaults="true" />
50
51 </behavior>
52
53 </serviceBehaviors>
54
55 </behaviors>
56
57 <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
58
59 <bindings>
60
61 <netTcpBinding>
62
63 <binding name="defaultBinding" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
64
65 <security mode="None">
66
67 <message clientCredentialType="None"/>
68
69 <transport clientCredentialType="None"></transport>
70
71 </security>
72
73 <readerQuotas />
74
75 </binding>
76
77 </netTcpBinding>
78
79 </bindings>
80
81 </system.serviceModel>
复制代码
(3) 在windows服务启动的时候启动WCF服务
复制代码
1 using SelfHelper;
2
3 using System;
4
5 using System.Collections.Generic;
6
7 using System.ComponentModel;
8
9 using System.Data;
10
11 using System.Diagnostics;
12
13 using System.Linq;
14
15 using System.ServiceProcess;
16
17 using System.Text;
18
19 using System.ServiceModel;
20
21
22
23 namespace SelfSQL
24
25 {
26
27 public partial class SelfSQLServer : ServiceBase
2
bf8f
8
29 {
30
31 public SelfSQLServer()
32
33 {
34
35 InitializeComponent();
36
37 }
38
39
40
41 ServiceHost host = new ServiceHost(typeof(SelfWcfService.SelfSQLData));
42
43 protected override void OnStart(string[] args)
44
45 {
46
47 LogWriter.WriteLog("服务已启动!");
48
49 try
50
51 {
52
53 host.Open();
54
55 LogWriter.WriteLog("WCF启动成功");
56
57 }
58
59 catch (Exception ex)
60
61 {
62
63 LogWriter.WriteLog("WCF启动异常:" + ex.ToString());
64
65 }
66
67
68
69 }
70
71
72
73 protected override void OnStop()
74
75 {
76
77 LogWriter.WriteLog("服务已停止!");
78
79 }
80
81 }
82
83 }
复制代码
(4) 启动windows服务进行测试
第3步:创建客户端进行测试
首先在控制台程序中添加服务引用
然后就可以调用客户端对象进行测试了。
测试代码:
复制代码
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Data;
6
7 using System.Linq;
8
9 using System.Text;
10
11
12
13 namespace SelfSQLClient
14
15 {
16
17 class Program
18
19 {
20
21 static void Main(string[] args)
22
23 {
24
25 SelfSQLServiceCilent.SelfSQLDataClient client = new SelfSQLServiceCilent.SelfSQLDataClient();
26
27 DataTable dt1 = new DataTable();
28
29
30
31 DataColumn idColumn = new DataColumn();
32
33 idColumn.DataType = System.Type.GetType("System.Int32");
34
35 idColumn.ColumnName = "t1";
36
37 idColumn.AutoIncrement = true;
38
39 dt1.Columns.Add(idColumn);
40
41
42
43 DataColumn aColumn = new DataColumn();
44
45 aColumn.DataType = System.Type.GetType("System.Int32");
46
47 aColumn.ColumnName = "t2";
48
49 aColumn.AutoIncrement = false;
50
51 dt1.Columns.Add(aColumn);
52
53
54
55 DataColumn bColumn = new DataColumn();
56
57 bColumn.DataType = System.Type.GetType("System.DateTime");
58
59 bColumn.ColumnName = "t3";
60
61 bColumn.AutoIncrement = false;
62
63 dt1.Columns.Add(bColumn);
64
65
66
67 for (int i = 0; i < 3; i++)
68
69 {
70
71 DataRow dr = dt1.NewRow();
72
73 dr[0] = i;
74
75 dr[1] = i + 1;
76
77 dr[2] = DateTime.Now;
78
79 dt1.Rows.Add(dr);
80
81 }
82
83 dt1.TableName = "FirstTable";
84
85 client.CreateTable("FirstTable", dt1);
86
87
88
89 Dictionary<string, DataTable> dts = client.GetData();
90
91 foreach (var dt in dts)
92
93 {
94
95 Console.WriteLine("表名:" + dt.Key);
96
97 string colNames = string.Empty;
98
99 foreach (var col in dt.Value.Columns)
100
101 {
102
103 colNames += col.ToString() + "--";
104
105 }
106
107 Console.WriteLine("字段:" + colNames);
108
109 foreach (DataRow val in dt.Value.Rows)
110
111 {
112
113 string vals = string.Empty;
114
115 for (int i = 0; i < dt.Value.Columns.Count; i++)
116
117 {
118
119 vals += val[i] + "--";
120
121 }
122
123 Console.WriteLine("数据:" + vals);
124
125 }
126
127 }
128
129 }
130
131 }
132
133 }
复制代码
输出结果:
添加SecondTable表:
输出结果:
总结:
到这里相信大家都知道了,所谓的“缓存数据库”不过是个数据结构为Dictionary<string,DataTable>的静态变量而已,有人可能要问,直接定义在应用程序中不就完事了吗?还有必要又是创建WCF服务,又是创建Windows服务的吗?当然,在这里像玩具一般的“缓存数据库”确实没必要这么大费周章,它并不友好,要新增数据需要大量初始化DataTable对象的代码,它也承载不了太大的数据量,毕竟内存依旧在CLR托管堆中,它的稳定性与安全性更是无从谈起,因为毫无并发量较高的逻辑处理,但是,我做这件事情的初衷,并不是要写一个可以匹敌类似于redis一样的数据库,而是如前言所说,正因为这个“玩具”它存在这么多的缺陷,那么对这些缺陷进行一定程度完善的过程,也是加深对多线程、设计模式、非关系型数据库等方面学习的一个过程。
分类: .net技术学习
好文要顶 关注我 收藏该文
布拉德皮特
关注 - 7
粉丝 - 0
+加关注
1 0
« 上一篇:以List为例浅谈C#的学习方法
posted @ 2018-01-05 12:37 布拉德皮特 阅读(229) 评论(5) 编辑 收藏
评论列表
#1楼 2018-01-05 13:00 数据酷软件
支持一下,为博主敢想敢干点赞。看起来其实可行。最后放的图在手机上看的时候迷惑了,以为还有内容在加载啊。呵呵呵,坏蛋。
支持(0)反对(0)
#2楼[楼主] 2018-01-05 13:05 布拉德皮特
@ 数据酷软件
感谢支持,你不说我都没注意文章末尾的加载图,已经干掉它了
支持(0)反对(0)
#3楼 2018-01-05 13:16 沈赟
谢谢分享
支持(0)反对(0)
#4楼[楼主] 2018-01-05 13:19 布拉德皮特
@ 沈赟
不客气,能有所帮助就好
支持(0)反对(0)
#5楼 2018-01-05 14:59 xzjl10
tinyurl.com/y8hc9qla
tinyurl.com/ya683n9c
tinyurl.com/y8jv5u37
tinyurl.com/yb38d8za
tinyurl.com/ycbdgups
tinyurl.com/ybgw3fvr
tinyurl.com/y74unklu
tinyurl.com/y8qqhh9w
tinyurl.com/y7wc42fv
tinyurl.com/y7zlds2e
tinyurl.com/yayvl6hh
tinyurl.com/y7yghr2y
tinyurl.com/ycy3wgw7
tinyurl.com/ybkd99zn
tinyurl.com/y78bte8q
tinyurl.com/y82q9t2r
tinyurl.com/y7m2jlma
tinyurl.com/yawr7eve
tinyurl.com/y6wpvdp3
tinyurl.com/ybwdd3m9
tinyurl.com/y92cfhqm
tinyurl.com/y8sh3uju
tinyurl.com/y9mvhcdv
tinyurl.com/yb8d5ff4
tinyurl.com/yax8yq7j
tinyurl.com/ycgz94mm
tinyurl.com/ydawmjgn
tinyurl.com/y7a2frzo
tinyurl.com/y84gt9cp
tinyurl.com/ya73ddeb
tinyurl.com/ydhsy6nf
tinyurl.com/ybu8ls9s
tinyurl.com/yam3z62a
tinyurl.com/y85qark7
tinyurl.com/y74gzpje
tinyurl.com/yc44xfgk
tinyurl.com/yb9mkxmj
tinyurl.com/ychrnmu4
tinyurl.com/y8mv6skk
tinyurl.com/y7eq36d2
tinyurl.com/yaphnwm6
tinyurl.com/y77uoj6a
tinyurl.com/y9o7vuld
tinyurl.com/y9ah8n7t
tinyurl.com/ya4vm5yu
tinyurl.com/yb4hrqpp
tinyurl.com/yanr4jc8
tinyurl.com/y9tco4z7
tinyurl.com/yc5rjsqz
tinyurl.com/y98qm9uv
tinyurl.com/yddwnzy3
tinyurl.com/y8olq8uz
tinyurl.com/y9j36noj
tinyurl.com/y8vh4t4a
tinyurl.com/y7ncy6tp
tinyurl.com/ybsz2ewu
tinyurl.com/y6vggshl
tinyurl.com/y7puuabm
完成这部分模型,大概会做一下几件事情:
微信约战斗地主棋牌开发( h5.super-mans.com Q:2012035031)
1、 创建一个Windows服务(用来寄存这个“缓存数据库”)
2、 创建一个WCF服务,寄宿在windows服务中(用于跟客户端通信,对“缓存数据库”进行增删查操作)
3、 创建客户端进行测试
第1步:WCF服务的创建及对缓存对象增删查的实现
WCF服务创建的过程及其Endpoint节点相关基础在这里不作累述,网上很多资料,这里直接贴Contract及其实现的代码,保存表数据的数据结构是Dictionary<string,DataTable>,其中key存放是表名,DataTable存放是数据。
复制代码
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Data;
6
7 using System.Linq;
8
9 using System.Runtime.Serialization;
10
11 using System.ServiceModel;
12
13 using System.ServiceModel.Web;
14
15 using System
4000
.Text;
16
17
18
19 namespace SelfWcfService
20
21 {
22
23 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
24
25 [ServiceContract]
26
27 public interface ISelfSQLData
28
29 {
30
31 [OperationContract]
32
33 ExcuteResult CreateTable(string tableName, DataTable colNames);
34
35
36
37 [OperationContract]
38
39 ExcuteResult Insert(string tableName, SelfDataRow dr);
40
41
42
43 [OperationContract]
44
45 ExcuteResult Delete(string tableName, SelfDataRow dr);
46
47
48
49 [OperationContract]
50
51 ExcuteResult DropTable(string tableName);
52
53
54
55 [OperationContract]
56
57 Dictionary<string, DataTable> GetData();
58
59 }
60
61
62
63 [DataContract]
64
65 public class SQLData
66
67 {
68
69 [DataMember]
70
71 public Dictionary<string, DataTable> DataTables { get; set; }
72
73 }
74
75
76
77 [DataContract]
78
79 public class SelfDataRow
80
81 {
82
83 [DataMember]
84
85 public DataTable DataTable { get; set; }
86
87 }
88
89 }
复制代码
接口实现部分:
微信约战斗地主棋牌开发( h5.super-mans.com Q:2012035031)
复制代码
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Data;
6
7 using System.Linq;
8
9 using System.Runtime.Serialization;
10
11 using System.ServiceModel;
12
13 using System.ServiceModel.Web;
14
15 using System.Text;
16
17
18
19 namespace SelfWcfService
20
21 {
22
23 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
24
25 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
26
27 public class SelfSQLData : ISelfSQLData
28
29 {
30
31 private static SQLData _sqlData;
32
33 public static SQLData SqlData
34
35 {
36
37 get
38
39 {
40
41 if (_sqlData == null)
42
43 {
44
45 _sqlData = new SQLData();
46
47 }
48
49 if (_sqlData.DataTables == null)
50
51 {
52
53 _sqlData.DataTables = new Dictionary<string, System.Data.DataTable>();
54
55 }
56
57 return _sqlData;
58
59 }
60
61 set
62
63 {
64
65 _sqlData = value;
66
67 }
68
69 }
70
71
72
73 private void InitalSqlData()
74
75 {
76
77 if (_sqlData == null)
78
79 {
80
81 _sqlData = new SQLData();
82
83 }
84
85 if (_sqlData.DataTables == null)
86
87 {
88
89 _sqlData.DataTables = new Dictionary<string, System.Data.DataTable>();
90
91 }
92
93 }
94
95
96
97 public ExcuteResult CreateTable(string tableName, DataTable colNames)
98
99 {
100
101 if (string.IsNullOrWhiteSpace(tableName))
102
103 {
104
105 return new ExcuteResult(1, "表名不能为空!");
106
107 }
108
109 if (colNames == null || colNames.Columns.Count < 1)
110
111 {
112
113 return new ExcuteResult(1, "表字段不能为空!");
114
115 }
116
117 InitalSqlData();
118
119 if (!_sqlData.DataTables.ContainsKey(tableName))
120
121 {
122
123 try
124
125 {
126
127 _sqlData.DataTables.Add(tableName, colNames);
128
129 }
130
131 catch (Exception ex)
132
133 {
134
135 return new ExcuteResult(1, ex.Message);
136
137 }
138
139 return new ExcuteResult(0, "表" + tableName + "创建成功!");
140
141 }
142
143 else
144
145 {
146
147 return new ExcuteResult(1, "已存在名为'" + tableName + "'的表");
148
149 }
150
151 }
152
153
154
155 public ExcuteResult Insert(string tableName, SelfDataRow dr)
156
157 {
158
159 if (string.IsNullOrWhiteSpace(tableName))
160
161 {
162
163 return new ExcuteResult(1, "表名不能为空!");
164
165 }
166
167 if (dr == null)
168
169 {
170
171 return new ExcuteResult(1, "不能插入空的数据行!");
172
173 }
174
175 InitalSqlData();
176
177 if (!_sqlData.DataTables.ContainsKey(tableName))
178
179 {
180
181 try
182
183 {
184
185 _sqlData.DataTables[tableName].Rows.Add(dr.DataTable.Rows[0]);
186
187 }
188
189 catch (Exception ex)
190
191 {
192
193 return new ExcuteResult(1, ex.Message);
194
195 }
196
197 return new ExcuteResult(0, "数据新增成功!");
198
199 }
200
201 else
202
203 {
204
205 return new ExcuteResult(1, "表'" + tableName + "'不存在!");
206
207 }
208
209 }
210
211
212
213 public ExcuteResult Delete(string tableName, SelfDataRow dr)
214
215 {
216
217 if (string.IsNullOrWhiteSpace(tableName))
218
219 {
220
221 return new ExcuteResult(1, "表名不能为空!");
222
223 }
224
225 if (dr == null)
226
227 {
228
229 return new ExcuteResult(1, "请指定删除对象!");
230
231 }
232
233 InitalSqlData();
234
235 if (!_sqlData.DataTables.ContainsKey(tableName))
236
237 {
238
239 try
240
241 {
242
243 _sqlData.DataTables[tableName].Rows.Remove(dr.DataTable.Rows[0]);
244
245 }
246
247 catch (Exception ex)
248
249 {
250
251 return new ExcuteResult(1, ex.Message);
252
253 }
254
255 return new ExcuteResult(0, "数据删除成功!");
256
257 }
258
259 else
260
261 {
262
263 return new ExcuteResult(1, "表'" + tableName + "'不存在!");
264
265 }
266
267 }
268
269
270
271 public ExcuteResult DropTable(string tableName)
272
273 {
274
275 if (string.IsNullOrWhiteSpace(tableName))
276
277 {
278
279 return new ExcuteResult(1, "表名不能为空!");
280
281 }
282
283 InitalSqlData();
284
285 if (!_sqlData.DataTables.ContainsKey(tableName))
286
287 {
288
289 try
290
291 {
292
293 _sqlData.DataTables.Remove(tableName);
294
295 }
296
297 catch (Exception ex)
298
299 {
300
301 return new ExcuteResult(1, ex.Message);
302
303 }
304
305 return new ExcuteResult(0, "表" + tableName + "删除成功!");
306
307 }
308
309 else
310
311 {
312
313 return new ExcuteResult(1, "表'" + tableName + "'不存在!");
314
315 }
316
317 }
318
319
320
321 public Dictionary<string, DataTable> GetData()
322
323 {
324
325 return SqlData.DataTables;
326
327 }
328
329 }
330
331 }
复制代码
微信约战斗地主棋牌开发( h5.super-mans.com Q:2012035031)
整个WCF实现的逻辑都在上面了,web配置文件不需要改,因为它不以web的形式发布寄宿在IIS中,而是windows服务中。
第2步:将WCF寄宿在Windows服务中
Windows服务的创建、安装、启动在这里也不作累述,跟WCF一样,网上资料也很多。这里重点介绍一下将WCF寄宿在Windows服务中。
(1) 将wcf项目的dll引用到windows服务项目中
(2) 在app.config文件中配置WCF终结点
复制代码
1 <system.serviceModel>
2
3 <services>
4
5 <service behaviorConfiguration="BasicServiceBehavior"
6
7 name="SelfWcfService.SelfSQLData">
8
9 <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
10
11 contract="SelfWcfService.ISelfSQLData">
12
13 <!--<identity>
14
15 <dns value="192.168.1.4" />
16
17 </identity>-->
18
19 </endpoint>
20
21 <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
22
23 contract="IMetadataExchange" />
24
25 <host>
26
27 <baseAddresses>
28
29 <add baseAddress="net.tcp://localhost:9000/SelfSQLData.svc"/>
30
31 <add baseAddress="http://localhost:9001/SelfSQLData.svc"/>
32
33 </baseAddresses>
34
35 </host>
36
37 </service>
38
39 </services>
40
41 <behaviors>
42
43 <serviceBehaviors>
44
45 <behavior name="BasicServiceBehavior">
46
47 <serviceMetadata httpGetEnabled="true" />
48
49 <serviceDebug includeExceptionDetailInFaults="true" />
50
51 </behavior>
52
53 </serviceBehaviors>
54
55 </behaviors>
56
57 <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
58
59 <bindings>
60
61 <netTcpBinding>
62
63 <binding name="defaultBinding" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
64
65 <security mode="None">
66
67 <message clientCredentialType="None"/>
68
69 <transport clientCredentialType="None"></transport>
70
71 </security>
72
73 <readerQuotas />
74
75 </binding>
76
77 </netTcpBinding>
78
79 </bindings>
80
81 </system.serviceModel>
复制代码
(3) 在windows服务启动的时候启动WCF服务
复制代码
1 using SelfHelper;
2
3 using System;
4
5 using System.Collections.Generic;
6
7 using System.ComponentModel;
8
9 using System.Data;
10
11 using System.Diagnostics;
12
13 using System.Linq;
14
15 using System.ServiceProcess;
16
17 using System.Text;
18
19 using System.ServiceModel;
20
21
22
23 namespace SelfSQL
24
25 {
26
27 public partial class SelfSQLServer : ServiceBase
2
bf8f
8
29 {
30
31 public SelfSQLServer()
32
33 {
34
35 InitializeComponent();
36
37 }
38
39
40
41 ServiceHost host = new ServiceHost(typeof(SelfWcfService.SelfSQLData));
42
43 protected override void OnStart(string[] args)
44
45 {
46
47 LogWriter.WriteLog("服务已启动!");
48
49 try
50
51 {
52
53 host.Open();
54
55 LogWriter.WriteLog("WCF启动成功");
56
57 }
58
59 catch (Exception ex)
60
61 {
62
63 LogWriter.WriteLog("WCF启动异常:" + ex.ToString());
64
65 }
66
67
68
69 }
70
71
72
73 protected override void OnStop()
74
75 {
76
77 LogWriter.WriteLog("服务已停止!");
78
79 }
80
81 }
82
83 }
复制代码
(4) 启动windows服务进行测试
第3步:创建客户端进行测试
首先在控制台程序中添加服务引用
然后就可以调用客户端对象进行测试了。
测试代码:
复制代码
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Data;
6
7 using System.Linq;
8
9 using System.Text;
10
11
12
13 namespace SelfSQLClient
14
15 {
16
17 class Program
18
19 {
20
21 static void Main(string[] args)
22
23 {
24
25 SelfSQLServiceCilent.SelfSQLDataClient client = new SelfSQLServiceCilent.SelfSQLDataClient();
26
27 DataTable dt1 = new DataTable();
28
29
30
31 DataColumn idColumn = new DataColumn();
32
33 idColumn.DataType = System.Type.GetType("System.Int32");
34
35 idColumn.ColumnName = "t1";
36
37 idColumn.AutoIncrement = true;
38
39 dt1.Columns.Add(idColumn);
40
41
42
43 DataColumn aColumn = new DataColumn();
44
45 aColumn.DataType = System.Type.GetType("System.Int32");
46
47 aColumn.ColumnName = "t2";
48
49 aColumn.AutoIncrement = false;
50
51 dt1.Columns.Add(aColumn);
52
53
54
55 DataColumn bColumn = new DataColumn();
56
57 bColumn.DataType = System.Type.GetType("System.DateTime");
58
59 bColumn.ColumnName = "t3";
60
61 bColumn.AutoIncrement = false;
62
63 dt1.Columns.Add(bColumn);
64
65
66
67 for (int i = 0; i < 3; i++)
68
69 {
70
71 DataRow dr = dt1.NewRow();
72
73 dr[0] = i;
74
75 dr[1] = i + 1;
76
77 dr[2] = DateTime.Now;
78
79 dt1.Rows.Add(dr);
80
81 }
82
83 dt1.TableName = "FirstTable";
84
85 client.CreateTable("FirstTable", dt1);
86
87
88
89 Dictionary<string, DataTable> dts = client.GetData();
90
91 foreach (var dt in dts)
92
93 {
94
95 Console.WriteLine("表名:" + dt.Key);
96
97 string colNames = string.Empty;
98
99 foreach (var col in dt.Value.Columns)
100
101 {
102
103 colNames += col.ToString() + "--";
104
105 }
106
107 Console.WriteLine("字段:" + colNames);
108
109 foreach (DataRow val in dt.Value.Rows)
110
111 {
112
113 string vals = string.Empty;
114
115 for (int i = 0; i < dt.Value.Columns.Count; i++)
116
117 {
118
119 vals += val[i] + "--";
120
121 }
122
123 Console.WriteLine("数据:" + vals);
124
125 }
126
127 }
128
129 }
130
131 }
132
133 }
复制代码
输出结果:
添加SecondTable表:
输出结果:
总结:
到这里相信大家都知道了,所谓的“缓存数据库”不过是个数据结构为Dictionary<string,DataTable>的静态变量而已,有人可能要问,直接定义在应用程序中不就完事了吗?还有必要又是创建WCF服务,又是创建Windows服务的吗?当然,在这里像玩具一般的“缓存数据库”确实没必要这么大费周章,它并不友好,要新增数据需要大量初始化DataTable对象的代码,它也承载不了太大的数据量,毕竟内存依旧在CLR托管堆中,它的稳定性与安全性更是无从谈起,因为毫无并发量较高的逻辑处理,但是,我做这件事情的初衷,并不是要写一个可以匹敌类似于redis一样的数据库,而是如前言所说,正因为这个“玩具”它存在这么多的缺陷,那么对这些缺陷进行一定程度完善的过程,也是加深对多线程、设计模式、非关系型数据库等方面学习的一个过程。
分类: .net技术学习
好文要顶 关注我 收藏该文
布拉德皮特
关注 - 7
粉丝 - 0
+加关注
1 0
« 上一篇:以List为例浅谈C#的学习方法
posted @ 2018-01-05 12:37 布拉德皮特 阅读(229) 评论(5) 编辑 收藏
评论列表
#1楼 2018-01-05 13:00 数据酷软件
支持一下,为博主敢想敢干点赞。看起来其实可行。最后放的图在手机上看的时候迷惑了,以为还有内容在加载啊。呵呵呵,坏蛋。
支持(0)反对(0)
#2楼[楼主] 2018-01-05 13:05 布拉德皮特
@ 数据酷软件
感谢支持,你不说我都没注意文章末尾的加载图,已经干掉它了
支持(0)反对(0)
#3楼 2018-01-05 13:16 沈赟
谢谢分享
支持(0)反对(0)
#4楼[楼主] 2018-01-05 13:19 布拉德皮特
@ 沈赟
不客气,能有所帮助就好
支持(0)反对(0)
#5楼 2018-01-05 14:59 xzjl10
tinyurl.com/y8hc9qla
tinyurl.com/ya683n9c
tinyurl.com/y8jv5u37
tinyurl.com/yb38d8za
tinyurl.com/ycbdgups
tinyurl.com/ybgw3fvr
tinyurl.com/y74unklu
tinyurl.com/y8qqhh9w
tinyurl.com/y7wc42fv
tinyurl.com/y7zlds2e
tinyurl.com/yayvl6hh
tinyurl.com/y7yghr2y
tinyurl.com/ycy3wgw7
tinyurl.com/ybkd99zn
tinyurl.com/y78bte8q
tinyurl.com/y82q9t2r
tinyurl.com/y7m2jlma
tinyurl.com/yawr7eve
tinyurl.com/y6wpvdp3
tinyurl.com/ybwdd3m9
tinyurl.com/y92cfhqm
tinyurl.com/y8sh3uju
tinyurl.com/y9mvhcdv
tinyurl.com/yb8d5ff4
tinyurl.com/yax8yq7j
tinyurl.com/ycgz94mm
tinyurl.com/ydawmjgn
tinyurl.com/y7a2frzo
tinyurl.com/y84gt9cp
tinyurl.com/ya73ddeb
tinyurl.com/ydhsy6nf
tinyurl.com/ybu8ls9s
tinyurl.com/yam3z62a
tinyurl.com/y85qark7
tinyurl.com/y74gzpje
tinyurl.com/yc44xfgk
tinyurl.com/yb9mkxmj
tinyurl.com/ychrnmu4
tinyurl.com/y8mv6skk
tinyurl.com/y7eq36d2
tinyurl.com/yaphnwm6
tinyurl.com/y77uoj6a
tinyurl.com/y9o7vuld
tinyurl.com/y9ah8n7t
tinyurl.com/ya4vm5yu
tinyurl.com/yb4hrqpp
tinyurl.com/yanr4jc8
tinyurl.com/y9tco4z7
tinyurl.com/yc5rjsqz
tinyurl.com/y98qm9uv
tinyurl.com/yddwnzy3
tinyurl.com/y8olq8uz
tinyurl.com/y9j36noj
tinyurl.com/y8vh4t4a
tinyurl.com/y7ncy6tp
tinyurl.com/ybsz2ewu
tinyurl.com/y6vggshl
tinyurl.com/y7puuabm
相关文章推荐
- 关于PHP微信h5棋牌程序开发数据库的备份
- 微信开发(自定义菜单整套流程)
- 使用Java进行微信开发 4 创建自定义菜单
- 微信二次开发——自定义菜单
- [038] 微信公众帐号开发教程第14篇-自定义菜单的创建及菜单事件响应
- .NET快速信息化h5微信二八杠棋牌房卡网站系统开发搭建框架 V3.0 版本强势发布
- 微信自定义菜单开发json拼接
- 微信开发创建自定义菜单
- 【微信开发】01.数据库授权和连接
- C#开发微信门户及应用(48) - 在微信框架中整合CacheManager 缓存框架
- 微信公众帐号开发教程第15篇-自定义菜单的view类型(访问网页)
- Java开发框架spring实现自定义缓存标签
- [039] 微信公众帐号开发教程第15篇-自定义菜单的view类型(访问网页)
- 微信公众帐号开发教程第15篇-自定义菜单的view类型(访问网页)
- spring-redis缓存方案学习三:基于aop的自定义注解开发
- [038] 微信公众帐号开发教程第14篇-自定义菜单的创建及菜单事件响应 .
- 微信开发,内网穿透工具 自定义域名 固定域名
- Spring学习笔记(十一):关于微信开发时,用户名包含表情,保存到数据库出错的解决办法
- 微信开发-自定义菜单
- php 微信分享自定义标题 图片 描述接口开发