NBear学习之路1:利用视图创建多表关联的实体
若还不清楚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。
例如:
而通常我们需要使用多数据表中的数据项时,通常都是使用视图的,而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即可一次获取所要的结果。
通常在一些应用中所使用到的字段不仅仅来左一个数据表,如一个文章列表GirdView中,使用到了Content、User、Category三个表中的项。
关系图如下:

1
public interface Content : Entity2

{3
[PrimaryKey]4
int ID5

{6
get;7
}8

9
[ManyToManyQuery(typeof(ContentTag), LazyLoad = true)]10
Tag[] Tags11

{ get;set; }12

13
[FkReverseQuery(LazyLoad = false)]14
Category Category15

{16
get;17
set;18
}19

20
DateTime? ModifiedDate21

{22
get;23
set;24
}25

26
[FkReverseQuery(LazyLoad = false)]27
[MappingName("UserID")]28
User User29

{30
get;31
set;32
}33

34
[SqlType("nvarchar(100)")]35
string Title36

{37
get;38
set;39
}40

41
[SqlType("ntext")]42
string Body43

{44
get;45
set;46
}47

48
[SqlType("ntext")]49

string Summary
{ get;set;}50

51
[SqlType("nvarchar(250)")]52
string Link53

{54
get;55
set;56
}57

58
int TopSort59

{60
get;61
set;62
}63

64
bool Visible65

{66
get;67
set;68
}69

70
int Hits71

{72
get;73
set;74
}75

76
[SqlType("nvarchar(50)")]77
string IP78

{79
get;80
set;81
}82

83
bool AllowComment84

{85
get;86
set;87
}88

89
int CommentCount90

{91
get;92
set;93
}94

95
[FkQuery("Content", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]96
Comment[] Comments97

{98
get;99
set;100
}101
}1
public interface User : Entity2

{3
[PrimaryKey]4
int ID5

{6
get;7
}8

9
[SqlType("nvarchar(50)")]10
string Name11

{12
get;13
set;14
}15

16
[SqlType("nvarchar(50)")]17
string Email18

{19
get;20
set;21
}22

23
[FkQuery("UserID", Contained = true, LazyLoad = true)]24
UserProfile Profile25

{26
get;27
set;28
}29

30
[ManyToManyQuery(typeof(UserGroup), OrderBy = "{Name} DESC", LazyLoad = true)]31
[SerializationIgnore]32
Group[] Groups33

{34
get;35
set;36
}37

38
[ManyToManyQuery(typeof(UserRole), OrderBy = "{Name} DESC", LazyLoad = true)]39
[SerializationIgnore]40
Role[] Roles41

{42
get;43
set;44
}45

46
[FkQuery("UserID", OrderBy = "{Name} DESC", Contained = true, LazyLoad = true)]47
[SerializationIgnore]48
Tag[] Tags49

{50
get;51
set;52
}53

54
[FkQuery("User", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]55
[SerializationIgnore]56
Content[] Contents57

{58
get;59
set;60
}61

62
[FkQuery("User", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]63
[SerializationIgnore]64
Comment[] Comments65

{66
get;67
set;68
}69

70
[FkQuery("User", OrderBy = "{Name} DESC", Contained = true, LazyLoad = true)]71
[SerializationIgnore]72
Category[] Categories73

{74
get;75
set;76
}77

78
UserStatus Status79

{80
get;81
set;82
}83

84
[SqlType("nvarchar(50)")]85
string LogOnName86

{87
get;88
set;89
}90

91
[SqlType("nvarchar(50)")]92
string Password93

{94
get;95
set;96
}97

98
[SqlType("nvarchar(100)")]99
string PassQuestion100

{101
get;102
set;103
}104

105
[SqlType("nvarchar(100)")]106
string PassAnswer107

{108
get;109
set;110
}111

112
[FkQuery("UserID", Contained = true, LazyLoad = true)]113
UserPhone[] Phones114

{115
get;116
set;117
}118

119
[SqlType("nvarchar(30)")]120
string No121

{122
get;123
set;124
}125

126
[SqlType("nvarchar(4)")]127
string Sex128

{129
get;130
set;131
}132

133
DateTime? Birthday134

{135
get;136
set;137
}138

139
DateTime? CreateDate140

{141
get;142
set;143
}144

145
DateTime? LogOnDate146

{147
get;148
set;149
}150

151
int LogOnCount152

{153
get;154
set;155
}156
}1
public interface Category : Entity2

{3
[PrimaryKey]4
int ID5

{6
get;7
}8

9
[SqlType("nvarchar(50)")]10
string Name11

{12
get;13
set;14
}15

16
[SqlType("nvarchar(250)")]17
string Description18

{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 Parent30

{31
get;32
set;33
}34

35
[FkQuery("Parent", OrderBy = "{Name} DESC", LazyLoad = true)]36
Category[] Childs37

{38
get;39
set;40
}41

42
[FkQuery("Category", OrderBy = "{ID} DESC", Contained = true, LazyLoad = true)]43
[SerializationIgnore]44
Content[] Contents45

{46
get;47
set;48
}49

50
int Sort51

{52
get;53
set;54
}55

56
[FkReverseQuery(LazyLoad = true)]57
User User58

{59
get;60
set;61
}62

63
[FkReverseQuery(LazyLoad = true)]64
Group Group65

{66
get;67
set;68
}69

70
bool Visible71

{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:2 this.GridView1.DataBind();
1![]()
<%
# StrongTyped<Entities.User>(Container.DataItem).User.Name %>
会发现,每次绑定一行时都会进行一次Select查询。分页大小越大,查询的次数则越多。
<%
# StrongTyped<Entities.User>(Container.DataItem).User.Name %>而通常我们需要使用多数据表中的数据项时,通常都是使用视图的,而NBear强大的支持从视图生成实体的功能,这样,可以轻而易举地解决这类问题,并且将查询次数减到最少。
1.首先,先建立关联三个表项的视图。结合上面的实体定义的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
GO4

5
CREATE VIEW [v_Content]6
AS7
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
GO2.使用NBear.Tools.DbToEntityDesign.exe工具从数据库中生成实体定义代码:
1
[ReadOnly]2
[MappingName("v_Content")]3
public interface ContentView : Entity4

{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即可一次获取所要的结果。


浙公网安备 33010602011771号