若还不清楚NBear中如何实现ORM,请先阅读Teddy所写的《
NBearV3 Step by Step教程——ORM篇
》。
通常在一些应用中所使用到的字段不仅仅来左一个数据表,如一个文章列表GirdView中,使用到了Content、User、Category三个表中的项。
关系图如下:
Content.cs
1
public interface Content : Entity
2
{
3
[PrimaryKey]
4
int ID
5
{
6
get;
7
}
8
9
[ManyToManyQuery(typeof(ContentTag), LazyLoad = true)]
10
Tag[] Tags
11
{ get;set; }
12
13
[FkReverseQuery(LazyLoad = false)]
14
Category Category
15
{
16
get;
17
set;
18
}
19
20
DateTime? ModifiedDate
21
{
22
get;
23
set;
24
}
25
26
[FkReverseQuery(LazyLoad = false)]
27
[MappingName("UserID")]
28
User User
29
{
30
get;
31
set;
32
}
33
34
[SqlType("nvarchar(100)")]
35
string Title
36
{
37
get;
38
set;
39
}
40
41
[SqlType("ntext")]
42
string Body
43
{
44
get;
45
set;
46
}
47
48
[SqlType("ntext")]
49
string Summary
{ get;set;}
50
51
[SqlType("nvarchar(250)")]
52
string Link
53
{
54
get;
55
set;
56
}
57
58
int TopSort
59
{
60
get;
61
set;
62
}
63
64
bool Visible
65
{
66
get;
67
set;
68
}
69
70
int Hits
71
{
72
get;
73
set;
74
}
75
76
[SqlType("nvarchar(50)")]
77
string IP
78
{
79
get;
80
set;
81
}
82
83
bool AllowComment
84
{
85
get;
86
set;
87
}
88
89
int CommentCount
90
{
91
get;
92
set;
93
}
94
95
[FkQuery("Content", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]
96
Comment[] Comments
97
{
98
get;
99
set;
100
}
101
}
User.cs
1
public interface User : Entity
2
{
3
[PrimaryKey]
4
int ID
5
{
6
get;
7
}
8
9
[SqlType("nvarchar(50)")]
10
string Name
11
{
12
get;
13
set;
14
}
15
16
[SqlType("nvarchar(50)")]
17
string Email
18
{
19
get;
20
set;
21
}
22
23
[FkQuery("UserID", Contained = true, LazyLoad = true)]
24
UserProfile Profile
25
{
26
get;
27
set;
28
}
29
30
[ManyToManyQuery(typeof(UserGroup), OrderBy = "{Name} DESC", LazyLoad = true)]
31
[SerializationIgnore]
32
Group[] Groups
33
{
34
get;
35
set;
36
}
37
38
[ManyToManyQuery(typeof(UserRole), OrderBy = "{Name} DESC", LazyLoad = true)]
39
[SerializationIgnore]
40
Role[] Roles
41
{
42
get;
43
set;
44
}
45
46
[FkQuery("UserID", OrderBy = "{Name} DESC", Contained = true, LazyLoad = true)]
47
[SerializationIgnore]
48
Tag[] Tags
49
{
50
get;
51
set;
52
}
53
54
[FkQuery("User", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]
55
[SerializationIgnore]
56
Content[] Contents
57
{
58
get;
59
set;
60
}
61
62
[FkQuery("User", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]
63
[SerializationIgnore]
64
Comment[] Comments
65
{
66
get;
67
set;
68
}
69
70
[FkQuery("User", OrderBy = "{Name} DESC", Contained = true, LazyLoad = true)]
71
[SerializationIgnore]
72
Category[] Categories
73
{
74
get;
75
set;
76
}
77
78
UserStatus Status
79
{
80
get;
81
set;
82
}
83
84
[SqlType("nvarchar(50)")]
85
string LogOnName
86
{
87
get;
88
set;
89
}
90
91
[SqlType("nvarchar(50)")]
92
string Password
93
{
94
get;
95
set;
96
}
97
98
[SqlType("nvarchar(100)")]
99
string PassQuestion
100
{
101
get;
102
set;
103
}
104
105
[SqlType("nvarchar(100)")]
106
string PassAnswer
107
{
108
get;
109
set;
110
}
111
112
[FkQuery("UserID", Contained = true, LazyLoad = true)]
113
UserPhone[] Phones
114
{
115
get;
116
set;
117
}
118
119
[SqlType("nvarchar(30)")]
120
string No
121
{
122
get;
123
set;
124
}
125
126
[SqlType("nvarchar(4)")]
127
string Sex
128
{
129
get;
130
set;
131
}
132
133
DateTime? Birthday
134
{
135
get;
136
set;
137
}
138
139
DateTime? CreateDate
140
{
141
get;
142
set;
143
}
144
145
DateTime? LogOnDate
146
{
147
get;
148
set;
149
}
150
151
int LogOnCount
152
{
153
get;
154
set;
155
}
156
}
Category.cs
1
public interface Category : Entity
2
{
3
[PrimaryKey]
4
int ID
5
{
6
get;
7
}
8
9
[SqlType("nvarchar(50)")]
10
string Name
11
{
12
get;
13
set;
14
}
15
16
[SqlType("nvarchar(250)")]
17
string Description
18
{
19
get;
20
set;
21
}
22
23
[FkQuery("ParentID", Contained = true, LazyLoad = true)]
24
Setting Setting
{ get;set; }
25
26
[FkReverseQuery(LazyLoad = true)]
27
[MappingName("ParentID")]
28
[SerializationIgnore]
29
Category Parent
30
{
31
get;
32
set;
33
}
34
35
[FkQuery("Parent", OrderBy = "{Name} DESC", LazyLoad = true)]
36
Category[] Childs
37
{
38
get;
39
set;
40
}
41
42
[FkQuery("Category", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]
43
[SerializationIgnore]
44
Content[] Contents
45
{
46
get;
47
set;
48
}
49
50
int Sort
51
{
52
get;
53
set;
54
}
55
56
[FkReverseQuery(LazyLoad = true)]
57
User User
58
{
59
get;
60
set;
61
}
62
63
[FkReverseQuery(LazyLoad = true)]
64
Group Group
65
{
66
get;
67
set;
68
}
69
70
bool Visible
71
{
72
get;
73
set;
74
}
75
}
而每个表对应的实体是通过NBear创建的,如果在绑定GirdView时,使用Content[]来做DataSource,再通过强类型来获得Content.User和Content.Category,这样每次都会进行两次查询,如果绑定的列有N条,再绑定一个GirdView的总查询次数将为2N+1。
例如:
1
this
.GridView1.DataSource
=
gateway.GetPageSelector
<
Content
>
(Content._.CategoryID
==
categoryID, orderBy, pageSize).FindPage(pageNo);
2
this
.GridView1.DataBind();
在GirdView1中设置编定列,譬如Content.User.Name:
1
<%
# StrongTyped<Entities.User>(Container.DataItem).User.Name
%>
会发现,每次绑定一行时都会进行一次Select查询。分页大小越大,查询的次数则越多。
而通常我们需要使用多数据表中的数据项时,通常都是使用视图的,而NBear强大的支持从视图生成实体的功能,这样,可以轻而易举地解决这类问题,并且将查询次数减到最少。
1.首先,先建立关联三个表项的视图。结合上面的实体定义的SQL视图脚本如下:
SQL视图脚本
1
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[v_Content]') and OBJECTPROPERTY(id, N'IsView') = 1)
2
drop view [dbo].[v_Content]
3
GO
4
5
CREATE VIEW [v_Content]
6
AS
7
SELECT [Category].[Name] AS [CategoryName], [Category].[Sort] AS [CategorySort],
8
[Category].[Visible] AS [CategoryVisible], [Category].[Description] AS [CategoryDescription],
9
[Category].[ParentID] AS [CategoryParentID],
10
[Category].[User_ID] AS [CategoryUserID], [Category].[Group_ID] AS [CategoryGroupID],
11
[Content].[ID], [Content].[Category_ID], [Content].[ModifiedDate],
12
[Content].[UserID], [Content].[Title], [Content].[Body], [Content].[Summary],
13
[Content].[Link], [Content].[TopSort], [Content].[Visible],
14
[Content].[Hits], [Content].[IP], [Content].[AllowComment], [Content].[CommentCount],
15
[User].[Name] AS [UserName], [User].[Email] AS [UserEmail], [User].[Status] AS [UserStatus],
16
[User].[LogOnName] AS [UserLogOnName]
17
FROM [Content] INNER JOIN [Category] ON [Category].[ID] = [Content].[Category_ID]
18
INNER JOIN [User] ON [User].[ID] = [Content].[UserID]
19
GO
2.使用NBear.Tools.DbToEntityDesign.exe工具从数据库中生成实体定义代码:
ContentView.cs
1
[ReadOnly]
2
[MappingName("v_Content")]
3
public interface ContentView : Entity
4
{
5
[SqlType("nvarchar(50)")]
6
string CategoryName
{ get; }
7
8
int CategorySort
{ get; }
9
10
bool CategoryVisible
{ get; }
11
12
[SqlType("nvarchar(250)")]
13
string CategoryDescription
{ get; }
14
15
int CategoryParentID
{ get; }
16
17
int CategoryUserID
{ get; }
18
19
int CategoryGroupID
{ get; }
20
21
int ID
{ get; }
22
23
[MappingName("Category_ID")]
24
int CategoryID
{ get; }
25
26
DateTime ModifiedDate
{ get; }
27
28
int UserID
{ get; }
29
30
[SqlType("nvarchar(100)")]
31
string Title
{ get; }
32
33
[SqlType("ntext")]
34
string Summary
{ get; }
35
36
[SqlType("nvarchar(250)")]
37
string Link
{ get; }
38
39
int TopSort
{ get; }
40
41
bool Visible
{ get; }
42
43
int Hits
{ get; }
44
45
[SqlType("nvarchar(50)")]
46
string IP
{ get; }
47
48
bool AllowComment
{ get; }
49
50
int CommentCount
{ get; }
51
52
[SqlType("ntext")]
53
string UserName
{ get; }
54
55
[SqlType("nvarchar(50)")]
56
string UserEmail
{ get; }
57
58
int UserStatus
{ get; }
59
60
[SqlType("nvarchar(50)")]
61
string UserLogOnName
{ get; }
62
}
3.使用ContentView[]绑定到GirdView即可一次获取所要的结果。