1
1
### 1. C# API 概念
2
2
C# API本质上实现了.Net程序和DolphinDB服务器之间的消息传递和数据转换协议。
3
- C# API运行在.Net Framework 4.0 及以上环境。
3
+ C# API运行在.Net Framework 4.0 及以上环境
4
4
5
- C# API遵循面向接口编程的原则。C# API使用接口类Entity来表示DolphinDB返回的所有数据类型。在Entity接口类的基础上,根据DolphinDB的数据类型,C# API提供了6种拓展接口,分别是scalar,vector,matrix,set,dictionary,table。这些接口类都包含在 dolphindb.data包中。
5
+ ### 2. C#对象和DolphinDB对象之间的映射
6
+ C# API遵循面向接口编程的原则。C# API使用接口类IEntity来表示DolphinDB返回的所有数据类型。在IEntity接口类的基础上,根据DolphinDB的数据类型,C# API提供了7种拓展接口,分别是scalar,vector,matrix,set,dictionary,table和chart。这些接口类都包含在com.xxdb.data包中。
6
7
7
8
拓展的接口类|命名规则|例子
8
9
---|---|---
9
10
scalar|` Basic<DataType> ` |BasicInt, BasicDouble, BasicDate, etc.
10
11
vector,matrix|` Basic<DataType><DataForm> ` |BasicIntVector, BasicDoubleMatrix, BasicAnyVector, etc.
11
12
set, dictionary和table|` Basic<DataForm> ` |BasicSet, BasicDictionary, BasicTable.
13
+ chart|BasicChart|
12
14
13
15
“Basic”表示基本的数据类型接口,` <DataType> ` 表示DolphinDB数据类型名称,` <DataForm> ` 是一个DolphinDB数据形式名称。
14
16
15
- DolphinDB C# API 提供的最核心的对象是DBConnection,它主要的功能就是让C#应用可以通过它在DolphinDB服务器上执行脚本和函数,并在两者之间双向传递数据。
17
+ ### 3. C# API提供的主要函数
18
+ DolphinDB C# API 提供的最核心的对象是DBConnection,它主要的功能就是让C#应用可以通过它调用DolphinDB的脚本和函数,在C#应用和DolphinDB服务器之间互通数据。
16
19
DBConnection类提供如下主要方法:
17
20
18
21
| 方法名 | 详情 |
@@ -25,7 +28,7 @@ DBConnection类提供如下主要方法:
25
28
| isBusy()| 判断当前会话是否正忙|
26
29
| close()| 关闭当前会话|
27
30
28
- ### 2 . 建立DolphinDB连接
31
+ ### 4 . 建立DolphinDB连接
29
32
30
33
C# API通过TCP/IP协议连接到DolphinDB服务器。 在下列例子中,我们连接正在运行的端口号为8848的本地DolphinDB服务器:
31
34
@@ -45,7 +48,12 @@ public void Test_Connect(){
45
48
```
46
49
boolean success = conn.connect("localhost", 8848, "admin", "123456");
47
50
```
48
- 当不带用户名密码连接成功后,脚本在Guest权限下运行,后续运行中若需要提升权限,可以通过调用 ` conn.login('admin','123456',false) ` 登录获取权限。
51
+
52
+ 使用初始化脚本(initialScript)参数连接:
53
+ 当需要在APP里定义和使用公用的自定义函数时,可以使用initialScript传入函数定义脚本。这样做的好处是一、无需每次run的时候重复定义。二、API提供自动重连机制,当断线之后重连时会产生新的会话,如果初始化脚本参数不为空,API会在新的会话中自动执行初始化脚本重新注册函数,在一些网络不是很稳定但是APP需要持续运行的场景里,这个参数会非常有用。
54
+ ```
55
+ boolean success = conn.connect("localhost", 8848, "admin", "123456", "");
56
+ ```
49
57
50
58
### 3.运行脚本
51
59
@@ -57,87 +65,7 @@ conn.run("<SCRIPT>");
57
65
58
66
如果脚本只包含一条语句,如表达式,DolphinDB会返回一个数据对象;否则返回NULL对象。如果脚本包含多条语句,将返回最后一个对象。如果脚本含有错误或者出现网络问题,它会抛出IOException。
59
67
60
- ### 4. 运行函数
61
- 当一段逻辑需要被服务端脚本反复调用时,可以用DolphinDB脚本将逻辑封装成自定义函数,类似于存储过程,然后在C#程序中通过函数方式调用。
62
-
63
- 下面的示例展示C#程序调用DolhinDB的` add ` 函数,` add ` 函数有两个参数` x,y ` ,参数的存储位置不同,也会导致调用方式的不同,存在以下三种情况:
64
-
65
- * 所有参数都在DolphinDB Server端
66
-
67
- 变量 x, y 已经通过C#程序提前在服务器端生成。
68
- ```
69
- conn.run("x = [1,3,5];y = [2,4,6]");
70
- ```
71
- 那么在C#端要对这两个向量做加法运算,只需要直接使用` run(script) ` 的方式即可
72
- ```
73
- public void testFunction()
74
- {
75
- IVector result = (IVector) conn.run("add(x,y)");
76
- Console.WriteLine(result.getString());
77
- }
78
-
79
- ```
80
-
81
- * 部分参数在DolphinDB Server端存在
82
-
83
- 变量 x 已经通过C#程序提前在服务器端生成,参数 y 要在C#客户端生成
84
- ```
85
- conn.run("x = [1,3,5]");
86
- ```
87
- 这时就需要使用` 部分应用 ` 方式,把参数 x 固化在add函数内,具体请参考[ 部分应用文档] ( https://www.dolphindb.com/cn/help/PartialApplication.html ) 。
88
-
89
- ```
90
- public void testFunction()
91
- {
92
- List<IEntity> args = new List<IEntity>(1);
93
- BasicDoubleVector y = new BasicDoubleVector(3);
94
- y.setDouble(0, 2.5);
95
- y.setDouble(1, 3.5);
96
- y.setDouble(2, 5);
97
- args.Add(y);
98
- IVector result = (IVector)conn.run("add{x}", args);
99
- Console.WriteLine(result.getString());
100
- }
101
- ```
102
- * 两个参数都在C#客户端
103
- ```
104
- public void testFunction()
105
- {
106
- List<IEntity> args = new List<IEntity>(1);
107
- BasicDoubleVector x = new BasicDoubleVector(3);
108
- x.setDouble(0, 1.5);
109
- x.setDouble(1, 2.5);
110
- x.setDouble(2, 7);
111
- BasicDoubleVector y = new BasicDoubleVector(3);
112
- y.setDouble(0, 2.5);
113
- y.setDouble(1, 3.5);
114
- y.setDouble(2, 5);
115
- args.Add(x);
116
- args.Add(y);
117
- IVector result = (IVector)conn.run("add", args);
118
- Console.WriteLine(result.getString());
119
- }
120
- ```
121
-
122
- ### 5. 上传数据对象
123
- 当C#中的一些数据需要被服务端频繁的用到,那么每次调用的时候都上传一次肯定不是一个好的做法,这个时候可以使用upload方法,将数据上传到服务器并分配给一个变量,后续就可以重复使用这个变量。
124
- 变量名称可以使用三种类型的字符:字母,数字或下划线。 第一个字符必须是字母。
125
-
126
- ```
127
- public void testUpload()
128
- {
129
- Dictionary<string, IEntity> vars = new Dictionary<string, IEntity>();
130
- BasicDoubleVector vec = new BasicDoubleVector(3);
131
- vec.setDouble(0, 1.5);
132
- vec.setDouble(1, 2.5);
133
- vec.setDouble(2, 7);
134
- vars.Add("a",vec);
135
- conn.upload(vars);
136
- IEntity result = (IEntity)conn.run("accumulate(+,a)");
137
- Console.WriteLine(result.getString());
138
- }
139
- ```
140
- ### 6. 读取数据示例
68
+ ### 6.操作DolphinDB数据结构的数据
141
69
142
70
下面介绍建立DolphinDB连接后,在C#环境中,对不同DolphinDB数据类型进行操作,运行结果显示在Console窗口。
143
71
@@ -155,7 +83,7 @@ using dolphindb.data;
155
83
```
156
84
rand(`IBM`MSFT`GOOG`BIDU,10)
157
85
```
158
- 返回C#对象BasicStringVector。vector.rows()方法能够获取向量的大小。我们可以使用vector.get (i)方法按照索引访问向量元素。
86
+ 返回C#对象BasicStringVector。vector.rows()方法能够获取向量的大小。我们可以使用vector.getString (i)方法按照索引访问向量元素。
159
87
160
88
```
161
89
public void testStringVector(){
@@ -174,7 +102,10 @@ public void testDoubleVector(){
174
102
Console.WriteLine(v.rows());
175
103
Console.WriteLine(Math.Round(((BasicDouble)v.get(1)).getValue(), 4));
176
104
}
105
+ ```
106
+
177
107
108
+ ```
178
109
public void testAnyVector(){
179
110
BasicAnyVector v = (BasicAnyVector)conn.run("[1 2 3,3.4 3.5 3.6]");
180
111
Console.WriteLine(v.rows());
@@ -194,7 +125,7 @@ public void testSet(){
194
125
195
126
- 矩阵
196
127
197
- 要从整数矩阵中检索一个元素,可以使用getInt (row,)。 要获取行数和列数,可以使用函数rows ()和columns()。
128
+ 要从整数矩阵中检索一个元素,我们可以使用get (row,col )。 要获取行数和列数,我们可以使用函数rows ()和columns()。
198
129
199
130
```
200
131
public void testIntMatrix(){
@@ -226,7 +157,7 @@ public void testDictionary(){
226
157
227
158
- 表
228
159
229
- 要获取表的列,可以用table .getColumn(index),使用table. columns()和table.rows()来分别获取列和行数 。
160
+ 要获取表的列,我们可以调用table .getColumn(index);同样,我们可以调用table.getColumnName(index)获取列名。 对于列和行的数量,我们可以分别调用table. columns()和table.rows()。
230
161
231
162
```
232
163
public void testTable(){
@@ -242,48 +173,82 @@ public void testTable(){
242
173
```
243
174
public void testVoid(){
244
175
IEntity obj = conn.run("NULL");
245
- Console.WriteLine(obj.getDataType());
176
+ Assert.AreEqual(obj.getObject(), null);
177
+ }
178
+
179
+ ```
180
+
181
+ ### 7.调用DolphinDB函数
182
+
183
+ 调用的函数可以是内置函数或用户自定义函数。 下面的示例将一个double向量传递给服务器,并调用sum函数。
184
+
185
+ ```
186
+ public void testFunction(){
187
+ List<IEntity> args = new List<IEntity>(1);
188
+ BasicDoubleVector vec = new BasicDoubleVector(3);
189
+ vec.setDouble(0, 1.5);
190
+ vec.setDouble(1, 2.5);
191
+ vec.setDouble(2, 7);
192
+ args.Add(vec);
193
+ BasicDouble result = (BasicDouble)conn.run("sum", args);
194
+ Console.WriteLine(result.getValue());
246
195
}
247
196
248
197
```
249
198
199
+ ### 8.将对象上传到DolphinDB服务器
200
+
201
+ 我们可以将二进制数据对象上传到DolphinDB服务器,并将其分配给一个变量以备将来使用。 变量名称可以使用三种类型的字符:字母,数字或下划线。 第一个字符必须是字母。
250
202
251
- ### 7. 读写DolphinDB数据表
203
+ ```
204
+ public void testUpload(){
205
+
206
+ BasicTable tb = (BasicTable)conn.run("table(1..100 as id,take(`aaa,100) as name)");
207
+ Dictionary<string, IEntity> upObj = new Dictionary<string, IEntity>();
208
+ upObj.Add("table_uploaded", (IEntity)tb);
209
+ db.upload(upObj);
210
+ BasicIntVector v = (BasicIntVector)conn.run("table_uploaded.id");
211
+ Console.WriteLine(v.rows());
212
+ }
213
+
214
+ ```
215
+
216
+ ### 9. 如何将C#数据表对象保存到DolphinDB的数据库中
252
217
253
218
使用C# API的一个重要场景是,用户从其他数据库系统或是第三方WebAPI中取到数据,将数据进行清洗后存入DolphinDB数据库中,本节将介绍通过C# API将取到的数据上传并保存到DolphinDB的数据表中。
254
219
255
220
DolphinDB数据表按存储方式分为三种:
256
221
257
222
- 内存表: 数据仅保存在本节点内存,存取速度最快,但是节点关闭数据就不存在了。
258
223
- 本地磁盘表:数据保存在本地磁盘上,即使节点关闭,通过脚本就可以方便的从磁盘加载到内存。
259
- - 分布式表:数据分布在不同的节点 ,通过DolphinDB的分布式计算引擎,逻辑上仍然可以像本地表一样做统一查询。
224
+ - 分布式表:数据在物理上分布在不同的节点 ,通过DolphinDB的分布式计算引擎,逻辑上仍然可以像本地表一样做统一查询。
260
225
261
- ### 7.1 保存数据到DolphinDB内存表
226
+ 因为本地磁盘表和分布式表的数据追加方式基本相同,所以下面分两部分介绍内存表数据追加以及本地磁盘和分布式表的数据追加。
227
+ #### 9.1. 将数据保存到DolphinDB内存表
262
228
263
- DolphinDB提供多种方式来保存数据 :
264
- - 通过 insert into 保存单条数据 ;
265
- - 通过 tableInsert 函数批量保存多条数据 ;
229
+ DolphinDB提供三种方式将数据新增到内存表 :
230
+ - 通过 insert into 方式保存单点数据 ;
231
+ - 通过 tableInsert 函数保存多个数组对象 ;
266
232
- 通过 append! 函数保存表对象。
267
233
268
-
269
- 这几种方式的区别是接收的参数类型不同,具体业务场景中,可能从数据源取到的是单点数据,也可能是多个数组或者表的方式组成的数据集。
234
+ 这三种方式的区别是接收的参数类型不同,具体业务场景中,可能从数据源取到的是单点数据,也可能是多个数组或者表的方式组成的数据集。
270
235
271
236
下面分别介绍三种方式保存数据的实例,在例子中使用到的数据表有4个列,分别是` string,int,timestamp,double ` 类型,列名分别为` cstring,cint,ctimestamp,cdouble ` ,构建脚本如下:
272
237
```
273
238
t = table(10000:0,`cstring`cint`ctimestamp`cdouble,[STRING,INT,TIMESTAMP,DOUBLE])
274
239
share t as sharedTable
275
240
```
276
- 由于内存表是会话隔离的,所以GUI中创建的内存表只有当前GUI会话可见,如果需要在C#程序或者其他终端访问 ,需要通过share关键字在会话间共享内存表。
277
- ### 7 .1.1. 保存单点数据
278
- 若C#程序是每次获取单条数据记录保存到DolphinDB,那么可以通过SQL语句(insert into)保存数据 。
241
+ 由于内存表是会话隔离的,所以GUI中创建的内存表只有当前GUI会话可见,如果需要其他终端访问 ,需要通过share关键字在会话间共享内存表。
242
+ ##### 9 .1.1. 保存单点数据
243
+ 若C#程序是每次获取单条数据记录保存到DolphinDB,那么可以通过类似SQL语句的insert into 的方式保存数据 。
279
244
```
280
245
public void test_save_Insert(String str, int i, long ts, double dbl)
281
246
{
282
247
conn.run(String.Format("insert into sharedTable values('{0}',{1},{2},{3})",str,i,ts,dbl));
283
248
}
284
249
```
285
250
286
- ### 7 .1.2 使用tableInsert函数批量保存数据
251
+ ##### 9 .1.2. 使用多个数组方式保存
287
252
288
253
若C#程序获取的数据可以组织成List方式,使用tableInsert函数比较适合,这个函数可以接受多个数组作为参数,将数组追加到数据表中。
289
254
@@ -299,11 +264,11 @@ public void test_save_TableInsert(string[] strArray, int[] intArray, long[] tsAr
299
264
```
300
265
def saveData(v1,v2,v3,v4){tableInsert(sharedTable,v1,v2,v3,v4)}
301
266
```
302
- 然后再通过` conn.run("saveData",args) ` 运行函数。 虽然这样也能实现目标,但是对Java程序来说要多一次服务端的调用 ,多消耗了网络资源。
267
+ 然后再通过` conn.run("saveData",args) ` 运行函数, 虽然这样也能实现目标,但是对C#程序来说要多一次服务端的调用 ,多消耗了网络资源。
303
268
在本例中,使用了DolphinDB 中的` 部分应用 ` 这一特性,将服务端表名以` tableInsert{sharedTable} ` 这样的方式固化到tableInsert中,作为一个独立函数来使用。这样就不需要再使用自定义函数的方式实现。
304
- 具体的文档请参考[ 部分应用文档] ( https://www.dolphindb.com /cn/help/PartialApplication.html ) 。
269
+ 具体的文档请参考[ 部分应用文档] ( https://www.dolphindb.cn /cn/help/PartialApplication.html ) 。
305
270
306
- ### 7 .1.3 使用append!函数批量保存数据
271
+ ##### 9 .1.3. 使用表方式保存
307
272
若C#程序是从DolphinDB的服务端获取表数据做处理后保存到分布式表,那么使用append!函数会更加方便,append!函数接受一个表对象作为参数,将数据追加到数据表中。
308
273
309
274
```
@@ -313,7 +278,7 @@ public void test_save_table(BasicTable table1)
313
278
conn.run("append!{shareTable}", args);
314
279
}
315
280
```
316
- ### 7.2 保存数据到分布式表
281
+ #### 9.2. 将数据保存到本地磁盘表和分布式表
317
282
分布式表是DolphinDB推荐在生产环境下使用的数据存储方式,它支持快照级别的事务隔离,保证数据一致性; 分布式表支持多副本机制,既提供了数据容错能力,又能作为数据访问的负载均衡。
318
283
319
284
本例中涉及到的数据表可以通过如下脚本构建 :
@@ -346,28 +311,28 @@ List<IVector> cols = new List<IVector>() { new BasicBooleanVector(boolArray), ne
346
311
BasicTable table1 = new BasicTable(colNames, cols);
347
312
```
348
313
349
- ### 7.3 保存数据到本地磁盘表
314
+ #### 9.3. 将数据保存到本地磁盘表
350
315
通常本地磁盘表用于学习环境或者单机静态数据集测试,它不支持事务,不保证运行中的数据一致性,所以不建议在生产环境中使用。
351
316
352
317
```
353
- //使用DolphinDB脚本创建一个数据表
318
+ //使用本地磁盘表
354
319
dbPath = "C:/data/testDatabase"
355
320
tbName = 'tb1'
356
321
357
322
if(existsDatabase(dbPath)){dropDatabase(dbPath)}
358
323
db = database(dbPath,RANGE,2018.01.01..2018.12.31)
359
324
db.createPartitionedTable(t,tbName,'ctimestamp')
360
325
```
361
- DolphinDB提供loadTable方法可以加载本地磁盘表和分布式表,对于本地磁盘表而言,追加数据都是通过append!方式进行 。
326
+ DolphinDB提供loadTable方法同样可以加载本地磁盘表,通过append!追加数据 。
362
327
```
363
328
public void test_save_table(String dbPath, BasicTable table1)
364
329
{
365
330
List<IEntity> args = new List<IEntity>() { table1 };
366
331
conn.run(String.Format("append!{loadTable('%s','tb1')}",dbPath), args);
367
332
}
368
333
```
369
- ### 7.4 读取和使用表数据
370
- 在C# API中,表数据保存为BasicTable对象, 由于BasicTable是列式存储,所以要读取和使用所有desultory需要通过先取出列 ,再循环取出行的方式。
334
+ ### 10. 循环遍历BasicTable
335
+ 由于BasicTable是列式存储,所以需要通过先取出列 ,再循环取出行的方式。
371
336
372
337
例子中参数BasicTable的有4个列,分别是` STRING,INT,TIMESTAMP,DOUBLE ` 类型,列名分别为` cstring,cint,ctimestamp,cdouble ` 。
373
338
@@ -388,12 +353,12 @@ public void test_loop_basicTable(BasicTable table1)
388
353
}
389
354
```
390
355
391
- ### 8 . DolphinDB和C#之间的数据类型转换
356
+ ### 11 . DolphinDB和C#之间的数据类型转换
392
357
C# API提供了与DolphinDB内部数据类型对应的对象,通常是以Basic+<DataType >这种方式命名,比如BasicInt,BasicDate等等。
393
358
一些C#的基础类型,可以通过构造函数直接创建对应的DOlphinDB数据结构,比如` new BasicInt(4) ` ,` new BasicDouble(1.23) ` ,但是也有一些类型需要做一些转换,下面列出需要做简单转换的类型:
394
359
- ` CHAR ` 类型:DolphinDB中的` CHAR ` 类型以Byte形式保存,所以在C# API中用` BasicByte ` 类型来构造` CHAR ` ,例如` new BasicByte((byte)'c') `
395
360
- ` SYMBOL ` 类型:DolphinDB中的` SYMBOL ` 类型是对字符串的优化,可以提高DolphinDB对字符串数据存储和查询的效率,但是C#中并不需要这种类型,所以C# API不提供` BasicSymbol ` 这种对象,直接用` BasicString ` 来处理即可。
396
- - 时间类型:DolphinDB的时间类型是以整形或者长整形来描述的,DolphinDB提供` date, month, time, minute, second, datetime, timestamp, nanotime, nanotimestamp ` 九种类型的时间类型,最高精度可以到纳秒级。具体的描述可以参考[ DolphinDB时序类型和转换] ( https://www.dolphindb.com /cn/help/TemporalTypeandConversion.html ) 。由于C#也提供了` DateTime,TimeSpan ` 等数据类型,所以C# API在Utils类里提供了所有C#时间类型和int或long之间的转换函数。
361
+ - 时间类型:DolphinDB的时间类型是以整形或者长整形来描述的,DolphinDB提供` date, month, time, minute, second, datetime, timestamp, nanotime, nanotimestamp ` 九种类型的时间类型,最高精度可以到纳秒级。具体的描述可以参考[ DolphinDB时序类型和转换] ( https://www.dolphindb.cn /cn/help/TemporalTypeandConversion.html ) 。由于C#也提供了` DateTime,TimeSpan ` 等数据类型,所以C# API在Utils类里提供了所有C#时间类型和int或long之间的转换函数。
397
362
398
363
以下脚本展示C# API中DolphinDB时间类型与C#原生时间类型之间的对应关系:
399
364
```
@@ -433,7 +398,7 @@ long timestamp = Utils.countMilliseconds(dt);
433
398
需要注意,由于C#的DateTime和TimeSpan在精度上达不到纳秒级别,所以如果要操作纳秒精度的时间数据时,可以通过 ` NanoTimestamp.getInternalValue() ` 来获取内部保存的long值,不要通过DateTime和TimeSpan转换,否则会造成精度损失。
434
399
435
400
436
- ### 9 . C# 流数据 API
401
+ ### 12 . C# 流数据 API
437
402
438
403
C# 程序可以通过API订阅数据流,当流数据进入客户端后,C# API处理数据的方式有两种:
439
404
@@ -474,4 +439,4 @@ client.subscribe(serverIP, serverPort, tableName, new MyHandler(), offsetInt);
474
439
ThreadPooledClient client = new ThreadPooledClient(subscribePort);
475
440
476
441
client.subscribe(serverIP, serverPort, tableName, new MyHandler(), offsetInt);
477
- ```
442
+ ```
0 commit comments