LINQ学习之旅——第二站"LTQ"之ORM

时间:2023-01-10 11:52:55

  随着把Linq To Object中的所有标准查询操作符讲解完,对Linq To Object的介绍将告一段落,虽然觉得内容不少,但理解起来应该不复杂。接下来进入学习之旅的第二站"LTQ",即Linq To SQL,用于操作关系型数据库中的数据,基于关系型数据库中存在的关系数据模型建立与之对应的对象关系模型(Object Relation Model) 。简单来讲就是Linq To SQL可以使用对象操作的方式来操作关系型数据库中的数据。而作为Linq To SQL的开篇内容,我想对ORM框架做个简单地介绍,以及重点介绍一下Linq To SQL这个ORM框架中的几种对象——关系映射(Object Relation Mapping)的方法。

  面向对象的程序设计方法强调设计良好的类模型来代表真实世界中的事物,这些具体的事物就是对象,而这些对象都是有自己的状态,程序需要一种方法把这些状态保存下来,以便程序下次启动时可以继续上次程序的运行。显然将表示这些状态的数据信息存储在关系型数据库中是最好的方法,但是关系型数据库是根据关系模型以记录的方式来存储数据,而不是用对象方式来存储的,所以开发人员不得不在关系模型和对象模型之间进行转换。其实这是一种模式化的操作过程,但是容易出错并且一定程度分散了开发人员的精力。正因为是模式化的操作,所以有很多公司推出了能够自动在对象模型和关系模型之间转换的组件,统称ORM框架,比如Java系列的Hibernate,而LINQ TO SQL是NET系列针对SQL SERVER数据库推出的ORM框架,是SQL SERVER数据库的API。ORM框架将数据库的关系模型抽象成对象模型后,对数据库的访问就只能通过对象模型以标准的对象访问方式来进行,尽管LINQ TO SQL中的查询表达式非常像SQL语句,但操作的仍然是对象模型。

  对象——关系映射(ORM)是随着面向对象软件开发方法发展而产生的设计思想。对于关系型数据库中的关系型数据和面向对象语言中的对象其实是业务实体的两种表现形式,在内存中表现为对象,而在数据库中表现为关系型数据。内存中的对象之间存在关联和继承关系,而在数据库中虽然无法直接表示多对多的关联和继承关系,但可以表示主从关系。而ORM使得关系型数据和对象之间可以以自己熟悉的方式表示与对方的关系,对象——关系映射一般以中间件形式存在,主要为实现程序对象到关系型数据库数据的自动映射。其中LINQ TO SQL中是使用实体类(实体类其实是一个普通的自定义类型,只不过用于映射物理表,所以被称为实体类)来映射数据库中的物理表,数据库中的实体类和物理表相映射,实体类属性和物理表中的列相映射。在VS集成开发环境中提供了四种建立这种对象——关系映射的方法。以下对四种方法做一一介绍:

  (1)内联属性

  内联属性(Inline attribute)建立映射是指通过在实体类的定义代码中使用一些特定的属性(attribute)修饰类名或者属性(property),来指定该类或者属性(property)具体映射到数据库中的表或者表的某一列的方法。下面列出LINQ TO SQL中常用的部分属性(attribute):

LINQ学习之旅——第二站"LTQ"之ORM

其中以属性Table、Column以及Assocation最为常用,以下是属性Column和Assocation中的参数以及用途说明:

属性Column部分参数的列表

LINQ学习之旅——第二站"LTQ"之ORM

属性Assocation部分参数的列表:

LINQ学习之旅——第二站"LTQ"之ORM

 注:IsUnique参数是用来指示外键上的唯一约束,放在1对1的关系上

 下面我将通过一个具体的示例来说明内联属性的使用方法:

①内联属性修饰类

  i.学生(Student)类:

 1 //Student实体类映射到物理表student
2 [Table(Name ="dbo.student")]
3 class Student
4 {
5 //属性No映射到物理表中的列名sno、主键信息和数据类型
6 [Column(Name ="sno",IsPrimaryKey=true, DbType ="char(8) NOT NULL")]
7 publicstring No { get ; set ; }
8
9 //属性Name映射物理表中的列名sname和数据类型
10 [Column(Name ="sname", DbType ="varchar(10) NOT NULL")]
11 publicstring Name { get; set; }
12
13 [Column(Name ="sdept", DbType ="varchar(10)", CanBeNull =true)]
14 publicstring Dept { get; set; }
15
16 [Column(Name ="ssex", DbType ="char(2)", CanBeNull =true)]
17 publicstring Sex { get; set; }
18
19 [Column(Name ="sage", DbType ="int", CanBeNull =true)]
20 publicint Age { get; set; }
21
22
23 //作为一对多的一方可以用类型为EntitySet<T>的成员来对应多方
24 private EntitySet<Student_Course> _courses;
25 //Association标识Student和Student_Course之间存在一对多的关系
26 //Name代表数据库中外键名称
27 //ThisKey代表本类Student中的主键属性No
28 //OtherKey代表关联类Student_Course中的主键属性Sno
29 //Storage代表数据存储位置为私有变量_courses
30 //DeleteRule代表级联删除时的策略(默认值NO ACTION,指如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则产生错误并回滚DELETE)
31 [Association(Name ="FK_student", ThisKey ="No", OtherKey ="Sno", Storage ="_courses",DeleteRule="NO ACTION")]
32 public EntitySet<Student_Course> Courses
33 {
34 get { return _courses; }
35 set { _courses.Assign(value); }
36 }
37 }

  ii.课程(Course)类:

 1 //Course实体类映射到物理表course
2 [Table(Name ="dbo.course")]
3 class Course
4 {
5 //属性No映射到物理表中的列名cno、主键信息和数据类型
6 [Column(Name ="cno",IsPrimaryKey=true,DbType ="char(8)", CanBeNull =false)]
7 publicstring No { get; set; }
8
9 //属性Name映射物理表中的列名cname和数据类型
10 [Column(Name ="cname", DbType ="varchar(20) NOT NULL")]
11 publicstring Name { get; set; }
12
13 [Column(Name ="ccredit", DbType ="int", CanBeNull =true)]
14 publicint Credit { get; set; }
15
16 [Column(Name ="cpno", DbType ="char(8)", CanBeNull =true)]
17 publicstring Pno { get; set; }
18
19 //作为一对多的一方可以用类型为EntitySet<T>的成员来对应多方
20 private EntitySet<Student_Course> _students;
21 //Association标识Course和Student_Course之间存在一对多的关系
22 //Name代表数据库中外键名称
23 //ThisKey代表本类Course中的主键属性No
24 //OtherKey代表关联类Student_Course中的主键属性Cno
25 //Storage代表数据存储位置为私有变量_students
26 //DeleteRule代表级联删除时的策略(默认值NO ACTION,指如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则产生错误并回滚DELETE)
27 [Association(Name ="FK_course", ThisKey ="No", OtherKey ="Cno", Storage ="_students", DeleteRule ="NO ACTION")]
28 public EntitySet<Student_Course> Students
29 {
30 get { return _students; }
31 set { _students.Assign(value); }
32 }
33 }

  iii.成绩(Student_Course)类: 

 1 //Student_Course实体类映射到物理表sc
2 [Table(Name ="dbo.sc")]
3 class Student_Course
4 {
5 //属性Sno映射到物理表中的列名sno、主键信息和数据类型
6 [Column(Name ="sno", IsPrimaryKey =true, DbType ="char(8) NOT NULL")]
7 publicstring Sno { get; set; }
8
9 //属性Cno映射到物理表中的列名cno、主键信息和数据类型
10 [Column(Name ="cno", IsPrimaryKey =true, DbType ="char(8) NOT NULL")]
11 publicstring Cno { get; set; }
12
13 //属性Grade映射物理表中的列名grade和数据类型
14 [Column(Name ="grade", DbType ="int", CanBeNull =true)]
15 publicint Grade { get; set; }
16
17
18 //作为多对一的一方可以用类型为EntityRef<T>的成员来对应一方
19 private EntityRef<Student> _student;
20 //Association标识Student_Course和Student之间存在多对一的关系
21 //Name代表数据库中外键名称
22 //ThisKey代表本类Student_Course中的主键属性Sno
23 //OtherKey代表关联类Student中的主键属性No
24 //Storage代表数据存储位置为私有变量_student
25 [Association(Name ="FK_student", IsForeignKey =true, ThisKey ="Sno", OtherKey ="No", Storage ="_student")]
26 public Student Student
27 {
28 get { return _student.Entity; }
29 set { _student.Entity = value; }
30 }
31
32
33 //作为多对一的一方可以用类型为EntityRef<T>的成员来对应一方
34 private EntityRef<Course> _course;
35 //Association标识Student_Course和Course之间存在多对一的关系
36 //Name代表数据库中外键名称
37 //ThisKey代表本类Student_Course中的主键属性Cno
38 //OtherKey代表关联类Course中的主键属性No
39 //Storage代表数据存储位置为私有变量_course
40 [Association(Name ="FK_course", IsForeignKey =true, ThisKey ="Cno", OtherKey ="No", Storage ="_course")]
41 public Course Course
42 {
43 get { return _course.Entity; }
44 set { _course.Entity = value; }
45 }
46 }

②Main主函数

 1 staticvoid Main(string[] args)
2 {
3 //建立数据库通信类对象
4 DataContext dc =new DataContext("Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king");
5
6 //查询所有学生集合
7 Table<Student> students = dc.GetTable<Student>();
8 //查询所有科目集合
9 Table<Course> courses = dc.GetTable<Course>();
10
11 Console.WriteLine("学生选课情况:");
12 foreach (var stu in students)
13 {
14 Console.WriteLine("学生:");
15 Console.WriteLine("学号: "+ stu.No);
16 Console.WriteLine("姓名: "+ stu.Name);
17 Console.WriteLine("**************************************");
18
19 foreach (var sc in stu.Courses)
20 {
21
22 var course = (from c in courses where c.No == sc.Cno select c).Single();
23 Console.WriteLine("课号: "+ course.No);
24 Console.WriteLine("课名: "+ course.Name);
25 Console.WriteLine("成绩: "+ sc.Grade);
26 Console.WriteLine("---------------------------------");
27 }
28
29 Console.WriteLine();
30 }
31
32 Console.WriteLine("\n");
33
34
35 Console.WriteLine("科目被选情况:");
36 foreach (var c in courses)
37 {
38 Console.WriteLine("课程: ");
39 Console.WriteLine("课号: "+ c.No);
40 Console.WriteLine("课名: "+ c.Name);
41 Console.WriteLine("**************************************");
42
43 foreach (var sc in c.Students)
44 {
45 var student = (from stu in students where stu.No == sc.Sno select stu).Single();
46 Console.WriteLine("学号: "+ student.No);
47 Console.WriteLine("姓名: "+ student.Name);
48 Console.WriteLine("成绩: "+ sc.Grade);
49 Console.WriteLine("---------------------------------");
50 }
51
52 Console.WriteLine();
53 }
54
55 Console.Read();
56 }

③结果:这里省略(因为数据太多)

 如果只是做简单的查询数据库中的集合那么这三个属性Table、Column以及Assocation已经足够,但如果要使用数据库中的存储过程或者用户自定义函数,那么还需要使用Function、ResultType以及Parameter属性(Attribute)来映射。但用内联属性来映射数据库中的存储过程或者用户自定义函数,我们需要先定义一个继承于DataContext类(来自命名空间System.Data.Linq)的数据库通信类,再在这个自定义类中定义与数据库中相对应的存储过程和自定义函数,并通过内联属性Function、ResultType以及Parameter来映射,另外如果存储过程或自定义函数返回值为多个物理表字段组成的记录类型,那么我们还需要自定义与这些返回值相对应的实体类来辅助这些定义在数据库通信类中的存储过程和自定义函数。如下面这个示例:

①数据库中的储存过程

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORM存储过程
 1 --选择选了所有科目的学生
2 createprocedure SelectAllCourseStudent
3 as
4 select sno,sname from student
5 wherenotexists(
6 select*from course
7 wherenotexists(
8 select*from sc
9 where student.sno=sno and course.cno=cno
10 )
11 );
12
13 --获取指定专业的人数
14 createprocedure GetStudentCountByDept
15 @deptvarchar(10),@stu_countint output
16 as
17 select@stu_count=COUNT(*) from student where sdept=@dept;
18
19 --选出有基础课的科目
20 createprocedure SelectCourseByPno
21 as
22 select*from course whereISNULL(cpno,'')!='';
23
24
25 --获取学生集合和科目集合
26 createprocedure SelectStudent_Course
27 as
28 begin
29 select*from course;
30 select*from student;
31 end;
32
33
34 --可选科目数量
35 createprocedure GetCourseCount
36 as
37 begin
38 declare@coursecountint;
39 select@coursecount=COUNT(*) from course;
40 return@coursecount;
41 end;
42
43 --获取学生成绩
44 createprocedure GetStudentGrade
45 as
46 select student.sno,sname,cname,grade
47 from student,sc,course
48 where student.sno=sc.sno and sc.cno=course.cno;

②数据库中的自定义函数

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORM自定义函数
1 --获取当前时间
2 createfunction GetCurrentTime()
3 returnsdatetime
4 as
5 begin
6 declare@tdatetime;
7 set@t=GETDATE();
8 return@t;
9 end;

③自定义对应于存储过程或函数返回值类型的类(用于辅助数据库通信类中定义的存储过程和自定义函数)

i.辅助类1

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORM辅助类1
  1 ///<summary>
2 /// 这里所有的自定义类都是对应于通信类
3 /// DB_StudentDataContext 中的存储过程
4 /// 的返回类型;
5 ///</summary>
6
7 publicclass SelectAllCourseStudentResult
8 {
9 privatestring _sno;
10
11 privatestring _sname;
12
13 public SelectAllCourseStudentResult()
14 {
15 }
16
17 [Column(Storage="_sno", DbType="Char(8) NOT NULL", CanBeNull=false)]
18 publicstring sno
19 {
20 get
21 {
22 returnthis._sno;
23 }
24 set
25 {
26 if ((this._sno != value))
27 {
28 this._sno = value;
29 }
30 }
31 }
32
33 [Column(Storage="_sname", DbType="VarChar(10) NOT NULL", CanBeNull=false)]
34 publicstring sname
35 {
36 get
37 {
38 returnthis._sname;
39 }
40 set
41 {
42 if ((this._sname != value))
43 {
44 this._sname = value;
45 }
46 }
47 }
48 }
49
50 publicclass SelectCourseByPnoResult
51 {
52 privatestring _cno;
53
54 privatestring _cname;
55
56 private System.Nullable<int> _ccredit;
57
58 privatestring _cpno;
59
60 public SelectCourseByPnoResult()
61 {
62 }
63
64 [Column(Storage="_cno", DbType="Char(8) NOT NULL", CanBeNull=false)]
65 publicstring cno
66 {
67 get
68 {
69 returnthis._cno;
70 }
71 set
72 {
73 if ((this._cno != value))
74 {
75 this._cno = value;
76 }
77 }
78 }
79
80 [Column(Storage="_cname", DbType="VarChar(20) NOT NULL", CanBeNull=false)]
81 publicstring cname
82 {
83 get
84 {
85 returnthis._cname;
86 }
87 set
88 {
89 if ((this._cname != value))
90 {
91 this._cname = value;
92 }
93 }
94 }
95
96 [Column(Storage="_ccredit", DbType="Int")]
97 public System.Nullable<int> ccredit
98 {
99 get
100 {
101 returnthis._ccredit;
102 }
103 set
104 {
105 if ((this._ccredit != value))
106 {
107 this._ccredit = value;
108 }
109 }
110 }
111
112 [Column(Storage="_cpno", DbType="Char(8)")]
113 publicstring cpno
114 {
115 get
116 {
117 returnthis._cpno;
118 }
119 set
120 {
121 if ((this._cpno != value))
122 {
123 this._cpno = value;
124 }
125 }
126 }
127 }

 ii.辅助类2

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORM辅助类2
  1 publicclass StudentResult
2 {
3 privatestring _sno;
4
5 privatestring _sname;
6
7 privatestring _sdept;
8
9 privatestring _ssex;
10
11 private System.Nullable<int> _sage;
12
13 public StudentResult()
14 {
15 }
16
17 [Column(Storage="_sno", DbType="Char(8) NOT NULL", CanBeNull=false)]
18 publicstring sno
19 {
20 get
21 {
22 returnthis._sno;
23 }
24 set
25 {
26 if ((this._sno != value))
27 {
28 this._sno = value;
29 }
30 }
31 }
32
33 [Column(Storage="_sname", DbType="VarChar(10) NOT NULL", CanBeNull=false)]
34 publicstring sname
35 {
36 get
37 {
38 returnthis._sname;
39 }
40 set
41 {
42 if ((this._sname != value))
43 {
44 this._sname = value;
45 }
46 }
47 }
48
49 [Column(Storage="_sdept", DbType="VarChar(10)")]
50 publicstring sdept
51 {
52 get
53 {
54 returnthis._sdept;
55 }
56 set
57 {
58 if ((this._sdept != value))
59 {
60 this._sdept = value;
61 }
62 }
63 }
64
65 [Column(Storage="_ssex", DbType="Char(2)")]
66 publicstring ssex
67 {
68 get
69 {
70 returnthis._ssex;
71 }
72 set
73 {
74 if ((this._ssex != value))
75 {
76 this._ssex = value;
77 }
78 }
79 }
80
81 [Column(Storage="_sage", DbType="Int")]
82 public System.Nullable<int> sage
83 {
84 get
85 {
86 returnthis._sage;
87 }
88 set
89 {
90 if ((this._sage != value))
91 {
92 this._sage = value;
93 }
94 }
95 }
96 }
97
98 publicclass CourseResult
99 {
100 privatestring _cno;
101
102 privatestring _cname;
103
104 private System.Nullable<int> _ccredit;
105
106 privatestring _cpno;
107
108 public CourseResult()
109 {
110 }
111
112 [Column(Storage="_cno", DbType="Char(8) NOT NULL", CanBeNull=false)]
113 publicstring cno
114 {
115 get
116 {
117 returnthis._cno;
118 }
119 set
120 {
121 if ((this._cno != value))
122 {
123 this._cno = value;
124 }
125 }
126 }
127
128 [Column(Storage="_cname", DbType="VarChar(20) NOT NULL", CanBeNull=false)]
129 publicstring cname
130 {
131 get
132 {
133 returnthis._cname;
134 }
135 set
136 {
137 if ((this._cname != value))
138 {
139 this._cname = value;
140 }
141 }
142 }
143
144 [Column(Storage="_ccredit", DbType="Int")]
145 public System.Nullable<int> ccredit
146 {
147 get
148 {
149 returnthis._ccredit;
150 }
151 set
152 {
153 if ((this._ccredit != value))
154 {
155 this._ccredit = value;
156 }
157 }
158 }
159
160 [Column(Storage="_cpno", DbType="Char(8)")]
161 publicstring cpno
162 {
163 get
164 {
165 returnthis._cpno;
166 }
167 set
168 {
169 if ((this._cpno != value))
170 {
171 this._cpno = value;
172 }
173 }
174 }
175 }
176
177 publicclass StudentGradeResult
178 {
179
180 privatestring _sno;
181
182 privatestring _sname;
183
184 privatestring _cname;
185
186 private System.Nullable<int> _grade;
187
188 [Column(Storage ="_sno", DbType ="Char(8) NOT NULL", CanBeNull =false)]
189 publicstring sno
190 {
191 get
192 {
193 returnthis._sno;
194 }
195 set
196 {
197 if ((this._sno != value))
198 {
199 this._sno = value;
200 }
201 }
202 }
203
204 [Column(Storage ="_sname", DbType ="VarChar(10) NOT NULL", CanBeNull =false)]
205 publicstring sname
206 {
207 get
208 {
209 returnthis._sname;
210 }
211 set
212 {
213 if ((this._sname != value))
214 {
215 this._sname = value;
216 }
217 }
218 }
219
220 [Column(Storage ="_cname", DbType ="VarChar(20) NOT NULL", CanBeNull =false)]
221 publicstring cname
222 {
223 get
224 {
225 returnthis._cname;
226 }
227 set
228 {
229 if ((this._cname != value))
230 {
231 this._cname = value;
232 }
233 }
234 }
235
236 [Column(Storage ="_grade", DbType ="Int")]
237 public System.Nullable<int> grade
238 {
239 get
240 {
241 returnthis._grade;
242 }
243 set
244 {
245 if ((this._grade != value))
246 {
247 this._grade = value;
248 }
249 }
250 }
251 }

④自定义数据库通信类

 1 //自定义类DB_StudentDataContext映射到数据库DB_Student
2 [Database(Name="DB_Student")]
3 //映射到SQL SERVER的版本
4 [Provider(typeof(System.Data.Linq.SqlClient.Sql2008Provider))]
5 //自定义类DB_StudentDataContext继承DataContext
6 class DB_StudentDataContext:DataContext
7 {
8 //通过连接字符串初始化
9 public DB_StudentDataContext(string connection):base(connection)
10 {
11
12 }
13
14 #region 映射到存储过程
15
16 //映射到存储过程GetCourseCount
17 //返回类型为int
18 [Function(Name="dbo.GetCourseCount")]
19 [ResultType(typeof(int))]
20 publicint GetCourseCount()
21 {
22 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
23 return ((int)(result.ReturnValue));
24 }
25
26 //映射到带输出参数的存储过程GetStudentCountByDept
27 //映射到存储过程中的数据类型为varchar(10)的输入参数dept
28 //映射到存储过程中的数据类型为int的输出参数stu_count
29 [Function(Name="dbo.GetStudentCountByDept")]
30 publicint GetStudentCountByDept([Parameter(Name ="dept", DbType ="varchar(10)")]string dept, [Parameter(Name ="stu_count", DbType ="int")] ref System.Nullable<int> stu_count)
31 {
32 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), dept, stu_count);
33 stu_count = ((System.Nullable<int>)(result.GetParameterValue(1)));
34 return ((int)(result.ReturnValue));
35 }
36
37 //映射到返回值为单一集合的存储过程GetStudentCountByDept
38 //集合中元素类型为自定义类型SelectAllCourseStudentResult
39 [Function(Name ="dbo.SelectAllCourseStudent")]
40 public ISingleResult<SelectAllCourseStudentResult> SelectAllCourseStudent()
41 {
42 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
43 return ((ISingleResult<SelectAllCourseStudentResult>)(result.ReturnValue));
44 }
45
46 //映射到返回值为单一集合的存储过程SelectCourseByPno
47 //集合中元素类型为自定义类型SelectCourseByPnoResult
48 [Function(Name ="dbo.SelectCourseByPno")]
49 public ISingleResult<SelectCourseByPnoResult> SelectCourseByPno()
50 {
51 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
52 return ((ISingleResult<SelectCourseByPnoResult>)(result.ReturnValue));
53 }
54
55 //映射到返回值为多结果集的存储过程SelectStudent_Course
56 //集合1中元素类型为自定义类型StudentResult
57 //集合2中元素类型为自定义类型CourseResult
58 [Function(Name ="dbo.SelectStudent_Course")]
59 [ResultType(typeof(StudentResult))]
60 [ResultType(typeof(CourseResult))]
61 public IMultipleResults SelectStudent_Course()
62 {
63 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
64 return ((IMultipleResults)(result.ReturnValue));
65 }
66
67 //映射到返回值为单一集合的存储过程GetStudentGrade
68 //集合中元素类型为自定义类型StudentGradeResult
69 [Function(Name ="dbo.GetStudentGrade")]
70 public ISingleResult<StudentGradeResult> GetStudentGrade()
71 {
72 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
73 return ((ISingleResult<StudentGradeResult>)(result.ReturnValue));
74 }
75
76 #endregion
77
78 #region 映射到自定义函数
79
80 //映射到返回值为datetime类型的自定义函数GetCurrentTime
81 //属性IsComposable标识是存储过程还是自定义函数,True为函数,False为过程,默认为False
82 [Function(Name ="dbo.GetCurrentTime", IsComposable =true)]
83 public System.Nullable<System.DateTime> GetCurrentTime()
84 {
85 return ((System.Nullable<System.DateTime>)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
86 }
87
88 #endregion
89 }

⑤调用存储过程或自定义函数

 

 1 staticvoid Main(string[] args)
2 {
3 //建立数据库DB_Student通信类对象
4 DB_StudentDataContext sdc =new DB_StudentDataContext("Data Source=PC2009100514WBV;Initial Catalog=DB_Student;User ID=sa;Password=king");
5
6 //调用存储过程GetCourseCount
7 Console.WriteLine("可选科目数:{0}", sdc.GetCourseCount());
8
9 Console.WriteLine("\n");
10
11 int? count =0;
12 //调用存储过程GetStudentCountByDept
13 sdc.GetStudentCountByDept("计算机", ref count);
14 Console.WriteLine("计算机系的人数:{0}", count);
15
16 Console.WriteLine("\n");
17
18 //调用存储过程SelectAllCourseStudent
19 var students1 = sdc.SelectAllCourseStudent();
20 Console.WriteLine("选了所有科目的学生:");
21 foreach (var stu in students1)
22 {
23 Console.WriteLine(stu.sno);
24 Console.WriteLine(stu.sname);
25 }
26
27 Console.WriteLine("\n");
28
29 //调用存储过程SelectStudent_Course
30 var courses2 = sdc.SelectStudent_Course().GetResult<CourseResult>();
31 var students2 = sdc.SelectStudent_Course().GetResult<StudentResult>();
32
33 //调用存储过程SelectCourseByPno
34 var courses1 = (from c in sdc.SelectCourseByPno()
35 join c1 in courses2
36 on c.cpno equals c1.cno
37 select new { Name = c.cname, Pname = c1.cname });
38
39 Console.WriteLine("科目->基础科目");
40 foreach (var c in courses1)
41 {
42 Console.WriteLine("{0}->{1}", c.Name, c.Pname);
43 }
44
45 Console.WriteLine("\n");
46
47
48 //调用存储过程GetStudentGrade
49 var stu_grades = sdc.GetStudentGrade().Select(sg =>new { Sno = sg.sno, Sname = sg.sname, Cname = sg.cname, Grade = sg.grade });
50
51 Console.WriteLine("学生成绩:");
52 foreach (var sg in stu_grades)
53 {
54 Console.WriteLine(sg.ToString());
55 }
56
57 Console.WriteLine("\n");
58
59 //调用自定义函数GetCurrentTime
60 Console.WriteLine("当前时间:{0}", sdc.GetCurrentTime());
61
62 Console.Read();
63 }

 

 

 

⑥结果:略

使用内联属性进行对象——关系映射的缺陷在于映射信息需要在编译时就完全确定下来,一旦映射信息发生改变,那么就需要重新编译程序

  (2)XML映射文件

  使用XML映射文件进行对象——关系映射和内联属性建立映射的方法有类似之处,但与内联属性方法不同的是,使用XML配置文件可以把映射信息单独保存在XML文件中,而不是和实体类写在一起,这不仅减少了实体类的代码,也将实体类的代码编写的重点放在了业务逻辑上。还是同一个示例,现在我们把所有的映射信息单独放在一个xml配置文件里:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <Database Name="DB_Student" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
3 <Table Name="student">
4 <Type Name="Student">
5 <Column Name="sno" Member="No" IsPrimaryKey="True" DbType="char(8)" CanBeNull="False"/>
6 <Column Name="sname" Member="Name" DbType = "varchar(10) NOT NULL"/>
7 <Column Name = "sdept" Member="Dept" DbType = "varchar(10)" CanBeNull = "True"/>
8 <Column Name = "ssex" Member="Sex" DbType = "char(2)" CanBeNull = "True"/>
9 <Column Name = "sage" Member="Age" DbType = "int" CanBeNull = "True"/>
10 <Association Name = "FK_student" Member="Courses"
11 ThisKey = "No" OtherKey = "Sno" Storage = "_courses" DeleteRule="NO ACTION"/>
12 </Type>
13 </Table>
14
15 <Table Name="course">
16 <Type Name="Course">
17 <Column Name="cno" Member="No" IsPrimaryKey="True" DbType="char(8)" CanBeNull="False"/>
18 <Column Name="cname" Member="Name" DbType = "varchar(10) NOT NULL"/>
19 <Column Name="ccredit" Member="Credit" DbType = "int" CanBeNull = "True"/>
20 <Column Name = "cpno" Member="Pno" DbType = "char(8)" CanBeNull = "true"/>
21 <Association Name = "FK_course" Member="Students"
22 ThisKey = "No" OtherKey = "Cno" Storage = "_students" DeleteRule="NO ACTION"/>
23 </Type>
24 </Table>
25
26 <Table Name="sc">
27 <Type Name="Student_Course">
28 <Column Name="sno" Member="Sno" IsPrimaryKey="True" DbType="char(8)" CanBeNull="False"/>
29 <Column Name="cno" Member="Cno" IsPrimaryKey="True" DbType="char(8)" CanBeNull="False"/>
30 <Column Name = "grade" Member="Grade" DbType = "int" CanBeNull = "True"/>
31 <Association Name = "FK_student" Member="student" IsForeignKey ="True" ThisKey = "Sno" OtherKey = "No" Storage = "_student"/>
32 <Association Name = "FK_course" Member="course" IsForeignKey ="True" ThisKey = "Cno" OtherKey = "No" Storage = "_course"/>
33 </Type>
34 </Table>
35
36 <Function Name="dbo.GetCourseCount" Method="GetCourseCount">
37 <Return DbType="Int"/>
38 </Function>
39
40 <Function Name="dbo.GetCurrentTime" Method="GetCurrentTime" IsComposable="true">
41 <Return DbType="DateTime"/>
42 </Function>
43
44 <Function Name="dbo.GetStudentCountByDept" Method="GetStudentCountByDept">
45 <Parameter Name="dept" Parameter="dept" DbType="VarChar(10)"/>
46 <Parameter Name="stu_count" Parameter="stu_count" DbType="Int"/>
47 <Return DbType="Int"/>
48 </Function>
49
50 <Function Name="dbo.GetStudentGrade" Method="GetStudentGrade">
51 <ElementType Name="GetStudentGradeResult">
52 <Column Name="sno" Member="Sno" Storage="_Sno" DbType="Char(8)"/>
53 <Column Name="sname" Member="sname" Storage="_sname" DbType="VarChar(10)"/>
54 <Column Name="cname" Member="cname" Storage="_cname" DbType="VarChar(20)"/>
55 <Column Name="grade" Member="grade" Storage="_grade" DbType="Int"/>
56 </ElementType>
57 </Function>
58
59 <Function Name="dbo.SelectAllCourseStudent" Method="SelectAllCourseStudent">
60 <ElementType Name="SelectAllCourseStudentResult">
61 <Column Name="sno" Member="sno" Storage="_sno" DbType="Char(8)"/>
62 <Column Name="sname" Member="sname" Storage="_sname" DbType="VarChar(10)"/>
63 </ElementType>
64 </Function>
65
66 <Function Name="dbo.SelectCourseByPno" Method="SelectCourseByPno">
67 <ElementType Name="SelectCourseByPnoResult">
68 <Column Name="cno" Member="cno" Storage="_cno" DbType="Char(8)"/>
69 <Column Name="cname" Member="cname" Storage="_cname" DbType="VarChar(20)"/>
70 <Column Name="ccredit" Member="ccredit" Storage="_ccredit" DbType="Int"/>
71 <Column Name="cpno" Member="cpno" Storage="_cpno" DbType="Char(8)"/>
72 </ElementType>
73 </Function>
74
75 <Function Name="dbo.SelectStudent_Course" Method="SelectStudent_Course">
76 <ElementType Name="CourseResult">
77 <Column Name="cno" Member="cno" Storage="_cno" DbType="Char(8)"/>
78 <Column Name="cname" Member="cname" Storage="_cname" DbType="VarChar(20)"/>
79 <Column Name="ccredit" Member="ccredit" Storage="_ccredit" DbType="Int"/>
80 <Column Name="cpno" Member="cpno" Storage="_cpno" DbType="Char(8)"/>
81 </ElementType>
82 <ElementType Name="StudentResult">
83 <Column Name="sno" Member="sno" Storage="_sno" DbType="Char(8)"/>
84 <Column Name="sname" Member="sname" Storage="_sname" DbType="VarChar(10)"/>
85 <Column Name="sdept" Member="sdept" Storage="_sdept" DbType="VarChar(10)"/>
86 <Column Name="ssex" Member="ssex" Storage="_ssex" DbType="Char(2)"/>
87 <Column Name="sage" Member="sage" Storage="_sage" DbType="Int"/>
88 </ElementType>
89 </Function>
90
91 </Database>

①原本内联属性修饰的类现在改为

i.学生(Student)类:

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORMStudent类
 1 class Student
2 {
3 publicstring No { get; set; }
4
5 publicstring Name { get; set; }
6
7 publicstring Dept { get; set; }
8
9 publicstring Sex { get; set; }
10
11 publicint Age { get; set; }
12
13 private EntitySet<Student_Course> _courses;
14 public EntitySet<Student_Course> Courses
15 {
16 get { return _courses; }
17 set { _courses.Assign(value); }
18 }
19 }

ii.课程(Course)类:

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORMCourse类
 1 class Course
2 {
3 publicstring No { get; set; }
4
5 publicstring Name { get; set; }
6
7 publicint Credit { get; set; }
8
9 publicstring Pno { get; set; }
10
11 private EntitySet<Student_Course> _students;
12 public EntitySet<Student_Course> Students
13 {
14 get { return _students; }
15 set { _students.Assign(value); }
16 }
17 }

iii.成绩(Student_Course)类:

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORMStudent_Course类
 1 class Student_Course
2 {
3 publicstring Sno { get; set; }
4
5 publicstring Cno { get; set; }
6
7 publicint Grade { get; set; }
8
9 private EntityRef<Student> _student;
10 public Student Student
11 {
12 get { return _student.Entity; }
13 set { _student.Entity = value; }
14 }
15
16 private EntityRef<Course> _course;
17 public Course Course
18 {
19 get { return _course.Entity; }
20 set { _course.Entity = value; }
21 }
22 }

②原本自定义对应于存储过程或函数返回值类型的类现在修改为

i.辅助类1:

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORM辅助类1
  1 publicclass SelectAllCourseStudentResult
2 {
3 privatestring _sno;
4
5 privatestring _sname;
6
7 public SelectAllCourseStudentResult()
8 {
9 }
10
11 publicstring sno
12 {
13 get
14 {
15 returnthis._sno;
16 }
17 set
18 {
19 if ((this._sno != value))
20 {
21 this._sno = value;
22 }
23 }
24 }
25
26 publicstring sname
27 {
28 get
29 {
30 returnthis._sname;
31 }
32 set
33 {
34 if ((this._sname != value))
35 {
36 this._sname = value;
37 }
38 }
39 }
40 }
41
42 publicclass SelectCourseByPnoResult
43 {
44
45 privatestring _cno;
46
47 privatestring _cname;
48
49 private System.Nullable<int> _ccredit;
50
51 privatestring _cpno;
52
53 public SelectCourseByPnoResult()
54 {
55 }
56
57 publicstring cno
58 {
59 get
60 {
61 returnthis._cno;
62 }
63 set
64 {
65 if ((this._cno != value))
66 {
67 this._cno = value;
68 }
69 }
70 }
71
72 publicstring cname
73 {
74 get
75 {
76 returnthis._cname;
77 }
78 set
79 {
80 if ((this._cname != value))
81 {
82 this._cname = value;
83 }
84 }
85 }
86
87 public System.Nullable<int> ccredit
88 {
89 get
90 {
91 returnthis._ccredit;
92 }
93 set
94 {
95 if ((this._ccredit != value))
96 {
97 this._ccredit = value;
98 }
99 }
100 }
101
102 publicstring cpno
103 {
104 get
105 {
106 returnthis._cpno;
107 }
108 set
109 {
110 if ((this._cpno != value))
111 {
112 this._cpno = value;
113 }
114 }
115 }
116 }

ii.辅助类2:

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORM辅助类2
  1 publicclass StudentResult
2 {
3 privatestring _sno;
4
5 privatestring _sname;
6
7 privatestring _sdept;
8
9 privatestring _ssex;
10
11 private System.Nullable<int> _sage;
12
13 public StudentResult()
14 {
15 }
16
17 publicstring sno
18 {
19 get
20 {
21 returnthis._sno;
22 }
23 set
24 {
25 if ((this._sno != value))
26 {
27 this._sno = value;
28 }
29 }
30 }
31
32 publicstring sname
33 {
34 get
35 {
36 returnthis._sname;
37 }
38 set
39 {
40 if ((this._sname != value))
41 {
42 this._sname = value;
43 }
44 }
45 }
46
47 publicstring sdept
48 {
49 get
50 {
51 returnthis._sdept;
52 }
53 set
54 {
55 if ((this._sdept != value))
56 {
57 this._sdept = value;
58 }
59 }
60 }
61
62 publicstring ssex
63 {
64 get
65 {
66 returnthis._ssex;
67 }
68 set
69 {
70 if ((this._ssex != value))
71 {
72 this._ssex = value;
73 }
74 }
75 }
76
77 public System.Nullable<int> sage
78 {
79 get
80 {
81 returnthis._sage;
82 }
83 set
84 {
85 if ((this._sage != value))
86 {
87 this._sage = value;
88 }
89 }
90 }
91 }
92
93 publicclass CourseResult
94 {
95 privatestring _cno;
96
97 privatestring _cname;
98
99 private System.Nullable<int> _ccredit;
100
101 privatestring _cpno;
102
103 public CourseResult()
104 {
105 }
106
107 publicstring cno
108 {
109 get
110 {
111 returnthis._cno;
112 }
113 set
114 {
115 if ((this._cno != value))
116 {
117 this._cno = value;
118 }
119 }
120 }
121
122 publicstring cname
123 {
124 get
125 {
126 returnthis._cname;
127 }
128 set
129 {
130 if ((this._cname != value))
131 {
132 this._cname = value;
133 }
134 }
135 }
136
137 public System.Nullable<int> ccredit
138 {
139 get
140 {
141 returnthis._ccredit;
142 }
143 set
144 {
145 if ((this._ccredit != value))
146 {
147 this._ccredit = value;
148 }
149 }
150 }
151
152 publicstring cpno
153 {
154 get
155 {
156 returnthis._cpno;
157 }
158 set
159 {
160 if ((this._cpno != value))
161 {
162 this._cpno = value;
163 }
164 }
165 }
166 }
167
168 publicclass StudentGradeResult
169 {
170
171 privatestring _sno;
172
173 privatestring _sname;
174
175 privatestring _cname;
176
177 private System.Nullable<int> _grade;
178
179 publicstring sno
180 {
181 get
182 {
183 returnthis._sno;
184 }
185 set
186 {
187 if ((this._sno != value))
188 {
189 this._sno = value;
190 }
191 }
192 }
193
194 publicstring sname
195 {
196 get
197 {
198 returnthis._sname;
199 }
200 set
201 {
202 if ((this._sname != value))
203 {
204 this._sname = value;
205 }
206 }
207 }
208
209 publicstring cname
210 {
211 get
212 {
213 returnthis._cname;
214 }
215 set
216 {
217 if ((this._cname != value))
218 {
219 this._cname = value;
220 }
221 }
222 }
223
224 public System.Nullable<int> grade
225 {
226 get
227 {
228 returnthis._grade;
229 }
230 set
231 {
232 if ((this._grade != value))
233 {
234 this._grade = value;
235 }
236 }
237 }
238 }

③原先的自定义数据库通信类改为

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORMDBStudentContext类
 1 //自定义类DB_StudentDataContext继承DataContext
2 class DB_StudentDataContext:DataContext
3 {
4 //通过连接字符串和xml映射文件初始化
5 public DB_StudentDataContext(string connection,MappingSource map):base(connection,map)
6 {
7
8 }
9
10 #region 映射到存储过程
11
12 publicint GetCourseCount()
13 {
14 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
15 return ((int)(result.ReturnValue));
16 }
17
18 publicint GetStudentCountByDept(string dept, ref System.Nullable<int> stu_count)
19 {
20 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), dept, stu_count);
21 stu_count = ((System.Nullable<int>)(result.GetParameterValue(1)));
22 return ((int)(result.ReturnValue));
23 }
24
25 public ISingleResult<SelectAllCourseStudentResult> SelectAllCourseStudent()
26 {
27 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
28 return ((ISingleResult<SelectAllCourseStudentResult>)(result.ReturnValue));
29 }
30
31 public ISingleResult<SelectCourseByPnoResult> SelectCourseByPno()
32 {
33 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
34 return ((ISingleResult<SelectCourseByPnoResult>)(result.ReturnValue));
35 }
36
37 public IMultipleResults SelectStudent_Course()
38 {
39 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
40 return ((IMultipleResults)(result.ReturnValue));
41 }
42
43 public ISingleResult<StudentGradeResult> GetStudentGrade()
44 {
45 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
46 return ((ISingleResult<StudentGradeResult>)(result.ReturnValue));
47 }
48
49 #endregion
50
51 #region 映射到自定义函数
52
53 public System.Nullable<System.DateTime> GetCurrentTime()
54 {
55 return ((System.Nullable<System.DateTime>)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))).ReturnValue));
56 }
57
58 #endregion
59 }

④Main主函数

 

LINQ学习之旅——第二站"LTQ"之ORMLINQ学习之旅——第二站"LTQ"之ORMMian主函数
  1       staticvoid Main(string[] args)
2 {
3 //建立一个xml映射对象
4 XmlMappingSource map = XmlMappingSource.FromXml(File.ReadAllText(@"Mapping.xml"));
5
6 //建立数据库DB_Student通信类对象
7 DB_StudentDataContext sdc =new DB_StudentDataContext("Data Source=PC2009100514WBV;Initial Catalog=DB_Student;User ID=sa;Password=king",map);
8
9 //查询所有学生集合
10 Table<Student> students = sdc.GetTable<Student>();
11 //查询所有科目集合
12 Table<Course> courses = sdc.GetTable<Course>();
13
14 Console.WriteLine("学生选课情况:");
15 foreach (var stu in students)
16 {
17 Console.WriteLine("学生:");
18 Console.WriteLine("学号: "+ stu.No);
19 Console.WriteLine("姓名: "+ stu.Name);
20 Console.WriteLine("**************************************");
21
22 foreach (var sc in stu.Courses)
23 {
24
25 var course = (from c in courses where c.No == sc.Cno select c).Single();
26 Console.WriteLine("课号: "+ course.No);
27 Console.WriteLine("课名: "+ course.Name);
28 Console.WriteLine("成绩: "+ sc.Grade);
29 Console.WriteLine("---------------------------------");
30 }
31
32 Console.WriteLine();
33 }
34
35 Console.WriteLine("\n");
36
37
38 Console.WriteLine("科目被选情况:");
39 foreach (var c in courses)
40 {
41 Console.WriteLine("课程: ");
42 Console.WriteLine("课号: "+ c.No);
43 Console.WriteLine("课名: "+ c.Name);
44 Console.WriteLine("**************************************");
45
46 foreach (var sc in c.Students)
47 {
48 var student = (from stu in students where stu.No == sc.Sno select stu).Single();
49 Console.WriteLine("学号: "+ student.No);
50 Console.WriteLine("姓名: "+ student.Name);
51 Console.WriteLine("成绩: "+ sc.Grade);
52 Console.WriteLine("---------------------------------");
53 }
54
55 Console.WriteLine();
56 }
57
58
59 Console.WriteLine("\n");
60
61 //调用存储过程GetCourseCount
62 Console.WriteLine("可选科目数:{0}", sdc.GetCourseCount());
63
64 Console.WriteLine("\n");
65
66 int? count =0;
67 //调用存储过程GetStudentCountByDept
68 sdc.GetStudentCountByDept("计算机", ref count);
69 Console.WriteLine("计算机系的人数:{0}", count);
70
71 Console.WriteLine("\n");
72
73 //调用存储过程SelectAllCourseStudent
74 var students1 = sdc.SelectAllCourseStudent();
75 Console.WriteLine("选了所有科目的学生:");
76 foreach (var stu in students1)
77 {
78 Console.WriteLine(stu.sno);
79 Console.WriteLine(stu.sname);
80 }
81
82 Console.WriteLine("\n");
83
84 //调用存储过程SelectStudent_Course
85 var courses2 = sdc.SelectStudent_Course().GetResult<CourseResult>();
86 var students2 = sdc.SelectStudent_Course().GetResult<StudentResult>();
87
88 //调用存储过程SelectCourseByPno
89 var courses1 = (from c in sdc.SelectCourseByPno()
90 join c1 in courses2
91 on c.cpno equals c1.cno
92 select new { Name = c.cname, Pname = c1.cname });
93
94 Console.WriteLine("科目->基础科目");
95 foreach (var c in courses1)
96 {
97 Console.WriteLine("{0}->{1}", c.Name, c.Pname);
98 }
99
100 Console.WriteLine("\n");
101
102
103 //调用存储过程GetStudentGrade
104 var stu_grades = sdc.GetStudentGrade().Select(sg =>new { Sno = sg.sno, Sname = sg.sname, Cname = sg.cname, Grade = sg.grade });
105
106 Console.WriteLine("学生成绩:");
107 foreach (var sg in stu_grades)
108 {
109 Console.WriteLine(sg.ToString());
110 }
111
112 Console.WriteLine("\n");
113
114 Console.WriteLine("当前时间:{0}", sdc.GetCurrentTime());
115
116 Console.Read();
117 }

 

 

 

⑤结果:略

虽然用XML映射文件来进行对象——关系映射不用在重新编译实体类的代码前提下修改映射内容,但是使用DataContext加载映射文件会消耗额外的解析时间,所以每种方法都有优缺点,要针对实际的应用情况来决定,同时也要通过不断的测试。但这两种方法都有缺点,就是它们都需要手动维护映射信息。而下面就要说VS提供的两种可以自动产生映射信息的方法。

  (3)SqlMetal工具

   SqlMetal程序是VS提供的一个命令行工具程序,用于自定化生成映射数据库中物理表的实体类代码。以下是SqlMetal程序的使用语法:

LINQ学习之旅——第二站"LTQ"之ORM

  读者可以尝试一下使用其中的几条命令组合起来执行一下,让SqlMetal工具自动生成实体类cs文件,映射文件map或者dbml文件;

  (4)LINQ TO SQL设计器

为了可视化地创建映射数据库中的物理表的实体类定义代码,VS提供了LINQ TO SQL设计器,它允许使用拖放的方式来可视化地创建实体类定义代码:

①创建dbml文件:

LINQ学习之旅——第二站"LTQ"之ORM

②生成dbml文件:

LINQ学习之旅——第二站"LTQ"之ORM

③连接数据库

LINQ学习之旅——第二站"LTQ"之ORM

④把物理表、存储过程以及自定义函数拖入到设计视图

LINQ学习之旅——第二站"LTQ"之ORM

设计器包含三个文件:一个XML元数据文件(DbStudent.dbml),该文件指定了类是如何产生的。另一个XML文件包含设计器的布局信息(DBStudent.dbml.layout)。产生的类文件在一个单独的文件中(DBStudent.designer.cs);但设计器有个问题,就是存储过程无法返回多个结果集,比如我们把上述存储过程SelectStudent_Course拖入到设计视图中,生成的代码:

1 [global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.SelectStudent_Course")]
2 public ISingleResult<SelectStudent_CourseResult> SelectStudent_Course()
3 {
4 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
5 return ((ISingleResult<SelectStudent_CourseResult>)(result.ReturnValue));
6 }

从生成的代码来看,设计器对于多集合的返回,默认只返回存储过程中的第一个集合(select * from course),忽略了之后的集合(select * from student),如果要返回多个集合的话就需要我们手动修改存储过程的代码,先要定义一个对应于DBStudent.designer.cs文件中的DBStudentDataContext类的Parital修饰的DBStudentDataContext类,然后自定义两个对应于返回集合的实体类,最后修改存储过程的实现代码。上述自动生成的代码改为如下形式:

  1 partialclass DBStudentDataContext
2 {
3 //映射到返回值为多结果集的存储过程SelectStudent_Course
4 //集合1中元素类型为自定义类型StudentResult
5 //集合2中元素类型为自定义类型CourseResult
6 [Function(Name ="dbo.SelectStudent_Course")]
7 [ResultType(typeof(CourseResult))]
8 [ResultType(typeof(StudentResult))]
9 //自定义存储过程MultiSelectStudent_Course
10 public IMultipleResults MultiSelectStudent_Course()
11 {
12 IExecuteResult result =this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
13 return ((IMultipleResults)(result.ReturnValue));
14 }
15 }
16
17 //自定义类StudentResult
18 publicclass StudentResult
19 {
20 privatestring _sno;
21
22 privatestring _sname;
23
24 privatestring _sdept;
25
26 privatestring _ssex;
27
28 private System.Nullable<int> _sage;
29
30 public StudentResult()
31 {
32 }
33
34 [Column(Storage ="_sno", DbType ="Char(8) NOT NULL", CanBeNull =false)]
35 publicstring sno
36 {
37 get
38 {
39 returnthis._sno;
40 }
41 set
42 {
43 if ((this._sno != value))
44 {
45 this._sno = value;
46 }
47 }
48 }
49
50 [Column(Storage ="_sname", DbType ="VarChar(10) NOT NULL", CanBeNull =false)]
51 publicstring sname
52 {
53 get
54 {
55 returnthis._sname;
56 }
57 set
58 {
59 if ((this._sname != value))
60 {
61 this._sname = value;
62 }
63 }
64 }
65
66 [Column(Storage ="_sdept", DbType ="VarChar(10)")]
67 publicstring sdept
68 {
69 get
70 {
71 returnthis._sdept;
72 }
73 set
74 {
75 if ((this._sdept != value))
76 {
77 this._sdept = value;
78 }
79 }
80 }
81
82 [Column(Storage ="_ssex", DbType ="Char(2)")]
83 publicstring ssex
84 {
85 get
86 {
87 returnthis._ssex;
88 }
89 set
90 {
91 if ((this._ssex != value))
92 {
93 this._ssex = value;
94 }
95 }
96 }
97
98 [Column(Storage ="_sage", DbType ="Int")]
99 public System.Nullable<int> sage
100 {
101 get
102 {
103 returnthis._sage;
104 }
105 set
106 {
107 if ((this._sage != value))
108 {
109 this._sage = value;
110 }
111 }
112 }
113 }
114
115 //自定义类CourseResult
116 publicclass CourseResult
117 {
118 privatestring _cno;
119
120 privatestring _cname;
121
122 private System.Nullable<int> _ccredit;
123
124 privatestring _cpno;
125
126 public CourseResult()
127 {
128 }
129
130 [Column(Storage ="_cno", DbType ="Char(8) NOT NULL", CanBeNull =false)]
131 publicstring cno
132 {
133 get
134 {
135 returnthis._cno;
136 }
137 set
138 {
139 if ((this._cno != value))
140 {
141 this._cno = value;
142 }
143 }
144 }
145
146 [Column(Storage ="_cname", DbType ="VarChar(20) NOT NULL", CanBeNull =false)]
147 publicstring cname
148 {
149 get
150 {
151 returnthis._cname;
152 }
153 set
154 {
155 if ((this._cname != value))
156 {
157 this._cname = value;
158 }
159 }
160 }
161
162 [Column(Storage ="_ccredit", DbType ="Int")]
163 public System.Nullable<int> ccredit
164 {
165 get
166 {
167 returnthis._ccredit;
168 }
169 set
170 {
171 if ((this._ccredit != value))
172 {
173 this._ccredit = value;
174 }
175 }
176 }
177
178 [Column(Storage ="_cpno", DbType ="Char(8)")]
179 publicstring cpno
180 {
181 get
182 {
183 returnthis._cpno;
184 }
185 set
186 {
187 if ((this._cpno != value))
188 {
189 this._cpno = value;
190 }
191 }
192 }
193 }