ObjectQuery是一个结合ActiveRecord的强类型对象查询工具,功能类似 Ayende的NHibernate Query Generator ,但更强大。
使用示例:
Post[] findAll = Query.From(DB.Post).Where(DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();
object[][] groupby = Query.From(DB.Post).GroupBy(DB.Post.Title).FindAll(DB.Post.Title, Aggregate.Count(DB.Post));
DateTime? aggregate = Query.From(DB.Post).FindOne(Aggregate.Max(DB.Post.Created));
ObjectQuery是一个结合ActiveRecord的强类型对象查询工具,功能类似 Ayende的NHibernate Query Generator ,但更强大。
下载:ObjectQuery.src.rar 44KB
ObjectQuery.bin.rar 611KB
使用示例:
Post[] findAll = Query.From(DB.Post).Where(DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();
object[][] groupby = Query.From(DB.Post).GroupBy(DB.Post.Title).FindAll(DB.Post.Title, Aggregate.Count(DB.Post));
DateTime? aggregate = Query.From(DB.Post).FindOne(Aggregate.Max(DB.Post.Created));
Post findFirst = Query.From(DB.Post).OrderBy(DB.Post.Created.DescOrder()).FindFirst();
Post[] booltest = Query.From(DB.Post).Where(DB.Post.Published).FindAll();
Blog[] listtest = Query.From(DB.Blog).Where(DB.Blog.Posts.Count > 0).FindAll();
Post[] math = Query.From(DB.Post).Where(DB.Post.Id + 1 > 0).FindAll();
CREATE TABLE [dbo].[Blogs] (
[blog_id] [int] IDENTITY (1, 1) NOT NULL ,
[blog_name] [varchar] (50) NULL ,
[blog_author] [varchar] (50) NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[Posts] (
[post_id] [int] IDENTITY (1, 1) NOT NULL ,
[post_title] [varchar] (50) NULL ,
[post_contents] [text] NULL ,
[post_category] [varchar] (50) NULL ,
[post_blogid] [int] NULL ,
[post_created] [datetime] NULL ,
[post_published] [bit] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
ActiveRecord类定义:

ActiveRecord类定义
1
namespace ObjectQuery.Test
2

{
3
using System;
4
using System.Collections;
5
using System.Collections.Generic;
6
using Castle.ActiveRecord;
7
8
9
class Blog#region class Blog
10
[ActiveRecord("Blogs")]
11
public partial class Blog : ActiveRecordBase<Blog>
12
{
13
14
private Int32 _id;
15
16
private String _name;
17
18
private String _author;
19
20
private IList<Post> _posts = new List<Post>();
21
22
[PrimaryKey(PrimaryKeyType.Native, "blog_id")]
23
public Int32 Id
24
{
25
get
26
{
27
return this._id;
28
}
29
set
30
{
31
this._id = value;
32
}
33
}
34
35
[Property(Column="blog_name")]
36
public String Name
37
{
38
get
39
{
40
return this._name;
41
}
42
set
43
{
44
this._name = value;
45
}
46
}
47
48
[Property(Column="blog_author")]
49
public String Author
50
{
51
get
52
{
53
return this._author;
54
}
55
set
56
{
57
this._author = value;
58
}
59
}
60
61
[HasMany(Table="Posts", ColumnKey="post_blogid")]
62
public IList<Post> Posts
63
{
64
get
65
{
66
return this._posts;
67
}
68
set
69
{
70
this._posts = value;
71
}
72
}
73
}
74
#endregion
75
76
class Post#region class Post
77
[ActiveRecord("Posts")]
78
public partial class Post : ActiveRecordBase<Post>
79
{
80
81
private Int32 _id;
82
83
private String _title;
84
85
private String _contents;
86
87
private String _category;
88
89
private Nullable<System.DateTime> _created;
90
91
private Nullable<bool> _published;
92
93
private Blog _blog;
94
95
[PrimaryKey(PrimaryKeyType.Native, "post_id")]
96
public Int32 Id
97
{
98
get
99
{
100
return this._id;
101
}
102
set
103
{
104
this._id = value;
105
}
106
}
107
108
[Property(Column="post_title")]
109
public String Title
110
{
111
get
112
{
113
return this._title;
114
}
115
set
116
{
117
this._title = value;
118
}
119
}
120
121
[Property(Column="post_contents")]
122
public String Contents
123
{
124
get
125
{
126
return this._contents;
127
}
128
set
129
{
130
this._contents = value;
131
}
132
}
133
134
[Property(Column="post_category")]
135
public String Category
136
{
137
get
138
{
139
return this._category;
140
}
141
set
142
{
143
this._category = value;
144
}
145
}
146
147
[Property(Column="post_created")]
148
public Nullable<System.DateTime> Created
149
{
150
get
151
{
152
return this._created;
153
}
154
set
155
{
156
this._created = value;
157
}
158
}
159
160
[Property(Column="post_published")]
161
public Nullable<bool> Published
162
{
163
get
164
{
165
return this._published;
166
}
167
set
168
{
169
this._published = value;
170
}
171
}
172
173
[BelongsTo("post_blogid")]
174
public Blog Blog
175
{
176
get
177
{
178
return this._blog;
179
}
180
set
181
{
182
this._blog = value;
183
}
184
}
185
}
186
#endregion
187
}
188
二、将ActiveRecord类加入一个项目(ObjectQuery.Test),编译项目生成dll或者exe文件(ObjectQuery.Test.exe)。
三、通过命令行运行代码生成工具ObjectQuery.Generator.exe,生成ObjectQuery.gen.cs / .vb 文件。
ObjectQuery.Generator.exe cs e:\temp\ObjectQuery.Test.exe e:\temp

代码生成器生成的代码
1
//------------------------------------------------------------------------------
2
// <auto-generated>
3
// 此代码由工具生成。
4
// 运行库版本:2.0.50727.42
5
//
6
// 对此文件的更改可能会导致不正确的行为,并且如果
7
// 重新生成代码,这些更改将会丢失。
8
// </auto-generated>
9
//------------------------------------------------------------------------------
10
11
namespace ObjectQuery.Test
12

{
13
using System;
14
using System.Collections;
15
using System.Collections.Generic;
16
using ObjectQuery;
17
using ObjectQuery.Property;
18
19
20
public class DB
21
{
22
23
public static Criteria.BlogCriteria Blog = new Criteria.BlogCriteria();
24
25
public static Criteria.PostCriteria Post = new Criteria.PostCriteria();
26
}
27
28
public class Criteria
29
{
30
31
class BlogCriteria#region class BlogCriteria
32
public class BlogCriteria : AbstractCriteria<ObjectQuery.Test.Blog>
33
{
34
35
private ValueTypeProperty<int> _Id;
36
37
private StringProperty _Name;
38
39
private StringProperty _Author;
40
41
private ListProperty _Posts;
42
43
public BlogCriteria()
44
{
45
}
46
47
internal BlogCriteria(string path) :
48
base(path)
49
{
50
}
51
52
public ValueTypeProperty<int> Id
53
{
54
get
55
{
56
if ((((object)(_Id)) == null))
57
{
58
_Id = new ValueTypeProperty<int>((_path + ".Id"));
59
}
60
return _Id;
61
}
62
}
63
64
public StringProperty Name
65
{
66
get
67
{
68
if ((((object)(_Name)) == null))
69
{
70
_Name = new StringProperty((_path + ".Name"));
71
}
72
return _Name;
73
}
74
}
75
76
public StringProperty Author
77
{
78
get
79
{
80
if ((((object)(_Author)) == null))
81
{
82
_Author = new StringProperty((_path + ".Author"));
83
}
84
return _Author;
85
}
86
}
87
88
public ListProperty Posts
89
{
90
get
91
{
92
if ((((object)(_Posts)) == null))
93
{
94
_Posts = new ListProperty((_path + ".Posts"));
95
}
96
return _Posts;
97
}
98
}
99
}
100
#endregion
101
102
class PostCriteria#region class PostCriteria
103
public class PostCriteria : AbstractCriteria<ObjectQuery.Test.Post>
104
{
105
106
private ValueTypeProperty<int> _Id;
107
108
private StringProperty _Title;
109
110
private StringProperty _Contents;
111
112
private StringProperty _Category;
113
114
private ValueTypeProperty<System.Nullable<System.DateTime>> _Created;
115
116
private BooleanProperty _Published;
117
118
private BlogCriteria _Blog;
119
120
public PostCriteria()
121
{
122
}
123
124
internal PostCriteria(string path) :
125
base(path)
126
{
127
}
128
129
public ValueTypeProperty<int> Id
130
{
131
get
132
{
133
if ((((object)(_Id)) == null))
134
{
135
_Id = new ValueTypeProperty<int>((_path + ".Id"));
136
}
137
return _Id;
138
}
139
}
140
141
public StringProperty Title
142
{
143
get
144
{
145
if ((((object)(_Title)) == null))
146
{
147
_Title = new StringProperty((_path + ".Title"));
148
}
149
return _Title;
150
}
151
}
152
153
public StringProperty Contents
154
{
155
get
156
{
157
if ((((object)(_Contents)) == null))
158
{
159
_Contents = new StringProperty((_path + ".Contents"));
160
}
161
return _Contents;
162
}
163
}
164
165
public StringProperty Category
166
{
167
get
168
{
169
if ((((object)(_Category)) == null))
170
{
171
_Category = new StringProperty((_path + ".Category"));
172
}
173
return _Category;
174
}
175
}
176
177
public ValueTypeProperty<System.Nullable<System.DateTime>> Created
178
{
179
get
180
{
181
if ((((object)(_Created)) == null))
182
{
183
_Created = new ValueTypeProperty<System.Nullable<System.DateTime>>((_path + ".Created"));
184
}
185
return _Created;
186
}
187
}
188
189
public BooleanProperty Published
190
{
191
get
192
{
193
if ((((object)(_Published)) == null))
194
{
195
_Published = new BooleanProperty((_path + ".Published"));
196
}
197
return _Published;
198
}
199
}
200
201
public BlogCriteria Blog
202
{
203
get
204
{
205
if ((((object)(_Blog)) == null))
206
{
207
_Blog = new BlogCriteria((_path + ".Blog"));
208
}
209
return _Blog;
210
}
211
}
212
}
213
#endregion
214
}
215
}
216
四、将代码生成器生成的文件加入到项目中,就可以使用ObjectQuery的强大功能了。

测试代码
1
Post.DeleteAll();
2
Blog.DeleteAll();
3
4
Blog blog = new Blog();
5
blog.Name = "tinifish @ blog";
6
blog.Author = "tinifish";
7
blog.Save();
8
9
Blog blog1 = new Blog();
10
blog1.Name = "tinifish @ blog";
11
blog1.Author = "tinifish";
12
blog1.Save();
13
14
Post post = new Post();
15
post.Blog = blog;
16
post.Title = "I love Active Record";
17
post.Contents = "Indeed I do!";
18
post.Category = "dotnet";
19
post.Created = DateTime.Now;
20
post.Published = false;
21
post.Save();
22
23
Post post1 = new Post();
24
//post1.Blog = blog;
25
post1.Title = "Overloading post";
26
post1.Contents = "Indeed I do!";
27
post1.Category = "DOTNET";
28
post1.Created = DateTime.Now;
29
post1.Published = true;
30
post1.Save();
31
32
using (new SessionScope())
33
{
34
Post[] findAll = Query.From(DB.Post).Where(DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();
35
Assert.IsTrue(findAll.Length == 1 && findAll[0].Id == post1.Id);
36
37
Post[] findAll1 = Query.From(DB.Post).Where(DB.Post.Blog == blog
38
&& DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();
39
Assert.IsTrue(findAll1.Length == 0);
40
41
object[][] groupby = Query.From(DB.Post).GroupBy(DB.Post.Title).FindAll(DB.Post.Title, Aggregate.Count(DB.Post));
42
Assert.IsTrue(groupby.Length == 2);
43
44
DateTime? aggregate = Query.From(DB.Post).FindOne(Aggregate.Max(DB.Post.Created));
45
Post findFirst = Query.From(DB.Post).OrderBy(DB.Post.Created.DescOrder()).FindFirst();
46
Assert.AreEqual(aggregate, findFirst.Created);
47
48
Post[] booltest = Query.From(DB.Post).Where(DB.Post.Published).FindAll();
49
Assert.IsTrue(booltest.Length == 1 && booltest[0].Id == post1.Id);
50
51
Blog[] listtest = Query.From(DB.Blog).Where(DB.Blog.Posts.Count > 0).FindAll();
52
Assert.IsTrue(listtest.Length == 1 && listtest[0].Id == blog.Id);
53
54
Post[] math = Query.From(DB.Post).Where(DB.Post.Id + 1 > 0).FindAll();
55
项目所使用的NHibernate和Castle.ActiveRecord的版本为svn服务器上的最新版本。
这是我在博客园发的第一篇随笔,请大家多多支持。欢迎功能建议和意见反馈。
下载:ObjectQuery.src.rar 44KB
ObjectQuery.bin.rar 611KB
使用示例:
Post[] findAll = Query.From(DB.Post).Where(DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();
object[][] groupby = Query.From(DB.Post).GroupBy(DB.Post.Title).FindAll(DB.Post.Title, Aggregate.Count(DB.Post));
DateTime? aggregate = Query.From(DB.Post).FindOne(Aggregate.Max(DB.Post.Created));
Post findFirst = Query.From(DB.Post).OrderBy(DB.Post.Created.DescOrder()).FindFirst();
Post[] booltest = Query.From(DB.Post).Where(DB.Post.Published).FindAll();
Blog[] listtest = Query.From(DB.Blog).Where(DB.Blog.Posts.Count > 0).FindAll();
Post[] math = Query.From(DB.Post).Where(DB.Post.Id + 1 > 0).FindAll(); 
使用步骤:
一、通过数据库表定义或者直接写出ActiveRecord的类。
数据库表定义:
CREATE TABLE [dbo].[Blogs] (
[blog_id] [int] IDENTITY (1, 1) NOT NULL ,
[blog_name] [varchar] (50) NULL ,
[blog_author] [varchar] (50) NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Posts] (
[post_id] [int] IDENTITY (1, 1) NOT NULL ,
[post_title] [varchar] (50) NULL ,
[post_contents] [text] NULL ,
[post_category] [varchar] (50) NULL ,
[post_blogid] [int] NULL ,
[post_created] [datetime] NULL ,
[post_published] [bit] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
1
namespace ObjectQuery.Test2


{3
using System;4
using System.Collections;5
using System.Collections.Generic;6
using Castle.ActiveRecord;7
8
9

class Blog#region class Blog10
[ActiveRecord("Blogs")]11
public partial class Blog : ActiveRecordBase<Blog>12

{13
14
private Int32 _id;15
16
private String _name;17
18
private String _author;19
20
private IList<Post> _posts = new List<Post>();21
22
[PrimaryKey(PrimaryKeyType.Native, "blog_id")]23
public Int32 Id24

{25
get26

{27
return this._id;28
}29
set30

{31
this._id = value;32
}33
}34
35
[Property(Column="blog_name")]36
public String Name37

{38
get39

{40
return this._name;41
}42
set43

{44
this._name = value;45
}46
}47
48
[Property(Column="blog_author")]49
public String Author50

{51
get52

{53
return this._author;54
}55
set56

{57
this._author = value;58
}59
}60
61
[HasMany(Table="Posts", ColumnKey="post_blogid")]62
public IList<Post> Posts63

{64
get65

{66
return this._posts;67
}68
set69

{70
this._posts = value;71
}72
}73
}74
#endregion75
76

class Post#region class Post77
[ActiveRecord("Posts")]78
public partial class Post : ActiveRecordBase<Post>79

{80
81
private Int32 _id;82
83
private String _title;84
85
private String _contents;86
87
private String _category;88
89
private Nullable<System.DateTime> _created;90
91
private Nullable<bool> _published;92
93
private Blog _blog;94
95
[PrimaryKey(PrimaryKeyType.Native, "post_id")]96
public Int32 Id97

{98
get99

{100
return this._id;101
}102
set103

{104
this._id = value;105
}106
}107
108
[Property(Column="post_title")]109
public String Title110

{111
get112

{113
return this._title;114
}115
set116

{117
this._title = value;118
}119
}120
121
[Property(Column="post_contents")]122
public String Contents123

{124
get125

{126
return this._contents;127
}128
set129

{130
this._contents = value;131
}132
}133
134
[Property(Column="post_category")]135
public String Category136

{137
get138

{139
return this._category;140
}141
set142

{143
this._category = value;144
}145
}146
147
[Property(Column="post_created")]148
public Nullable<System.DateTime> Created149

{150
get151

{152
return this._created;153
}154
set155

{156
this._created = value;157
}158
}159
160
[Property(Column="post_published")]161
public Nullable<bool> Published162

{163
get164

{165
return this._published;166
}167
set168

{169
this._published = value;170
}171
}172
173
[BelongsTo("post_blogid")]174
public Blog Blog175

{176
get177

{178
return this._blog;179
}180
set181

{182
this._blog = value;183
}184
}185
}186
#endregion187
}188

二、将ActiveRecord类加入一个项目(ObjectQuery.Test),编译项目生成dll或者exe文件(ObjectQuery.Test.exe)。
三、通过命令行运行代码生成工具ObjectQuery.Generator.exe,生成ObjectQuery.gen.cs / .vb 文件。
ObjectQuery.Generator.exe cs e:\temp\ObjectQuery.Test.exe e:\temp
1
//------------------------------------------------------------------------------2
// <auto-generated>3
// 此代码由工具生成。4
// 运行库版本:2.0.50727.425
//6
// 对此文件的更改可能会导致不正确的行为,并且如果7
// 重新生成代码,这些更改将会丢失。8
// </auto-generated>9
//------------------------------------------------------------------------------10

11
namespace ObjectQuery.Test12


{13
using System;14
using System.Collections;15
using System.Collections.Generic;16
using ObjectQuery;17
using ObjectQuery.Property;18
19
20
public class DB21

{22
23
public static Criteria.BlogCriteria Blog = new Criteria.BlogCriteria();24
25
public static Criteria.PostCriteria Post = new Criteria.PostCriteria();26
}27
28
public class Criteria29

{30
31

class BlogCriteria#region class BlogCriteria32
public class BlogCriteria : AbstractCriteria<ObjectQuery.Test.Blog>33

{34
35
private ValueTypeProperty<int> _Id;36
37
private StringProperty _Name;38
39
private StringProperty _Author;40
41
private ListProperty _Posts;42
43
public BlogCriteria()44

{45
}46
47
internal BlogCriteria(string path) : 48
base(path)49

{50
}51
52
public ValueTypeProperty<int> Id53

{54
get55

{56
if ((((object)(_Id)) == null))57

{58
_Id = new ValueTypeProperty<int>((_path + ".Id"));59
}60
return _Id;61
}62
}63
64
public StringProperty Name65

{66
get67

{68
if ((((object)(_Name)) == null))69

{70
_Name = new StringProperty((_path + ".Name"));71
}72
return _Name;73
}74
}75
76
public StringProperty Author77

{78
get79

{80
if ((((object)(_Author)) == null))81

{82
_Author = new StringProperty((_path + ".Author"));83
}84
return _Author;85
}86
}87
88
public ListProperty Posts89

{90
get91

{92
if ((((object)(_Posts)) == null))93

{94
_Posts = new ListProperty((_path + ".Posts"));95
}96
return _Posts;97
}98
}99
}100
#endregion101
102

class PostCriteria#region class PostCriteria103
public class PostCriteria : AbstractCriteria<ObjectQuery.Test.Post>104

{105
106
private ValueTypeProperty<int> _Id;107
108
private StringProperty _Title;109
110
private StringProperty _Contents;111
112
private StringProperty _Category;113
114
private ValueTypeProperty<System.Nullable<System.DateTime>> _Created;115
116
private BooleanProperty _Published;117
118
private BlogCriteria _Blog;119
120
public PostCriteria()121

{122
}123
124
internal PostCriteria(string path) : 125
base(path)126

{127
}128
129
public ValueTypeProperty<int> Id130

{131
get132

{133
if ((((object)(_Id)) == null))134

{135
_Id = new ValueTypeProperty<int>((_path + ".Id"));136
}137
return _Id;138
}139
}140
141
public StringProperty Title142

{143
get144

{145
if ((((object)(_Title)) == null))146

{147
_Title = new StringProperty((_path + ".Title"));148
}149
return _Title;150
}151
}152
153
public StringProperty Contents154

{155
get156

{157
if ((((object)(_Contents)) == null))158

{159
_Contents = new StringProperty((_path + ".Contents"));160
}161
return _Contents;162
}163
}164
165
public StringProperty Category166

{167
get168

{169
if ((((object)(_Category)) == null))170

{171
_Category = new StringProperty((_path + ".Category"));172
}173
return _Category;174
}175
}176
177
public ValueTypeProperty<System.Nullable<System.DateTime>> Created178

{179
get180

{181
if ((((object)(_Created)) == null))182

{183
_Created = new ValueTypeProperty<System.Nullable<System.DateTime>>((_path + ".Created"));184
}185
return _Created;186
}187
}188
189
public BooleanProperty Published190

{191
get192

{193
if ((((object)(_Published)) == null))194

{195
_Published = new BooleanProperty((_path + ".Published"));196
}197
return _Published;198
}199
}200
201
public BlogCriteria Blog202

{203
get204

{205
if ((((object)(_Blog)) == null))206

{207
_Blog = new BlogCriteria((_path + ".Blog"));208
}209
return _Blog;210
}211
}212
}213
#endregion214
}215
}216

四、将代码生成器生成的文件加入到项目中,就可以使用ObjectQuery的强大功能了。
1
Post.DeleteAll();2
Blog.DeleteAll();3

4
Blog blog = new Blog();5
blog.Name = "tinifish @ blog";6
blog.Author = "tinifish";7
blog.Save();8

9
Blog blog1 = new Blog();10
blog1.Name = "tinifish @ blog";11
blog1.Author = "tinifish";12
blog1.Save();13

14
Post post = new Post();15
post.Blog = blog;16
post.Title = "I love Active Record";17
post.Contents = "Indeed I do!";18
post.Category = "dotnet";19
post.Created = DateTime.Now;20
post.Published = false;21
post.Save();22

23
Post post1 = new Post();24
//post1.Blog = blog;25
post1.Title = "Overloading post";26
post1.Contents = "Indeed I do!";27
post1.Category = "DOTNET";28
post1.Created = DateTime.Now;29
post1.Published = true;30
post1.Save();31

32
using (new SessionScope())33

{34
Post[] findAll = Query.From(DB.Post).Where(DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();35
Assert.IsTrue(findAll.Length == 1 && findAll[0].Id == post1.Id);36

37
Post[] findAll1 = Query.From(DB.Post).Where(DB.Post.Blog == blog38
&& DB.Post.Title.StartsWith("Overloading") || DB.Post.Title == "Operator").FindAll();39
Assert.IsTrue(findAll1.Length == 0);40

41
object[][] groupby = Query.From(DB.Post).GroupBy(DB.Post.Title).FindAll(DB.Post.Title, Aggregate.Count(DB.Post));42
Assert.IsTrue(groupby.Length == 2);43

44
DateTime? aggregate = Query.From(DB.Post).FindOne(Aggregate.Max(DB.Post.Created));45
Post findFirst = Query.From(DB.Post).OrderBy(DB.Post.Created.DescOrder()).FindFirst();46
Assert.AreEqual(aggregate, findFirst.Created);47

48
Post[] booltest = Query.From(DB.Post).Where(DB.Post.Published).FindAll();49
Assert.IsTrue(booltest.Length == 1 && booltest[0].Id == post1.Id);50

51
Blog[] listtest = Query.From(DB.Blog).Where(DB.Blog.Posts.Count > 0).FindAll();52
Assert.IsTrue(listtest.Length == 1 && listtest[0].Id == blog.Id);53

54
Post[] math = Query.From(DB.Post).Where(DB.Post.Id + 1 > 0).FindAll();55

项目所使用的NHibernate和Castle.ActiveRecord的版本为svn服务器上的最新版本。
这是我在博客园发的第一篇随笔,请大家多多支持。欢迎功能建议和意见反馈。
浙公网安备 33010602011771号