LINQ学习之旅——第二站"LTQ"之DataContext对象详解

  在上一节对对象——关系映射(ORM)方法的介绍以及对应的示例代码中,DataContext这个关键字经常被用到,而今天要讲解的主要内容就是围绕在LINQ TO SQL中和数据库经常打交道的DataContext对象展开的。也可以这样说,只要用到LINQ TO SQL技术,就离不开DataContext对象。它是LINQ TO SQL编程接口中最重要的一个组件,专门用于处理和数据库相关的操作,比如连接数据库、监视实体类的更改,将实体类的更改保存到数据库中以及缓存数据等任务,但在一般实际运用中,不是直接使用DataContext对象来完成特定的功能,而是通过使用一个继承于DataContext类的子类来实现与数据库的交流。因为DataContext对象在LINQ TO SQL中的重要性,所以单独用一节的内容来详细介绍一下DataContext对象中的方法、属性以及关键的特性。

  1.DataContext构造方法:

  DataContext类共有四种构造方法原型:

  ①public DataContext(string fileOrServerOrConnection);

  ②public DataContext(IDbConnection connection);

  ③public DataContext(string fileOrServerOrConnection, MappingSource mapping);

  ④public DataContext(IDbConnection connection, MappingSource mapping);  

第一种构造方法原型也是四种中最常用的方法,其原型可以接收一个数据库连接字符串或者一个数据库源文件路径来构造一个DataContext对象;第二种方法可以接收一个类型为IDbConnection的对象作为参数来构造,比如System.Data.SqlClient.SqlConnection类生成的对象来作为参数,因为该类继承于System.Data.Common.DbConnection类,而后者又继承于接口System.Data.IDbConnection;其实最后两种方法原型相对于前两种就是多了一个映射对象类型MappingSource的参数mapping,该参数用于定义实体类和数据库物理表之间的映射关系。下面用一个示例来说明DataContext构造方法的具体使用(注:代码中所用到类Student、Course以及Student_Course请参照上一节示例):

DataContext构造方法
 1 //DataContext第一种构造方法
2 string str_conn ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
3 DataContext dc=new DataContext(str_conn);
4 Table<Student> students = dc.GetTable<Student>();
5 dc.Dispose();
6
7 //DataContext第二种构造方法
8 System.Data.SqlClient.SqlConnection conn =new System.Data.SqlClient.SqlConnection(str_conn);
9 DataContext dc1 =new DataContext(conn);
10 Table<Course> courses = dc1.GetTable<Course>();
11 dc1.Dispose();
12
13 //DataContext第三种构造方法
14 XmlMappingSource map = XmlMappingSource.FromXml(System.IO.File.ReadAllText(@"Mapping.xml"));
15 DataContext dc2 =new DataContext(str_conn, map);
16 Table<Student_Course> scs = dc2.GetTable<Student_Course>();
17 dc2.Dispose();
18
19 //DataContext第四种构造方法
20 DataContext dc3 =new DataContext(conn, map);
21 Table<Student> students1 = dc3.GetTable<Student>();
22 dc3.Dispose();

  2.DataContext成员方法:

  (1)方法SubmitChanges

  SubmitChanges方法用于把程序中对实体类对象的更改信息保存到数据库中,在该方法调用之前,DataContext对象会缓存程序中对实体类对象的更改信息,如果最后不执行方法SubmitChanges,那么这些修改的信息就不会保存到数据库中,该方法有两个方法原型:

①void SubmitChanges();

②void SubmitChanges(ConflictMode failureMode);

第一个方法原型很普通就是把实体类修改信息保存到数据库中,而第二种原型比前一种多了一个类型为ConflictMode的参数failureMode,ConflictMode是一个枚举类型,它用来指定在将数据更改保存到数据库的过程中,如果发生并发冲突需要采取的处理策略其包含来两个枚举值FailOnFirstConflict和ContinueOnConflict,从各自的字面意思上也不难看出,前者是指在数据保存到数据库的过程中第一次发生并发冲突时,SubmitChanges方法立即抛出异常,而ContinueOnConflict允许发生并发冲突时继续更新后面的数据,最后再抛出一个全部更新失败信息的异常。相比较于FailOnFirstConflict,ContinueOnConflict能把更新数据过程中所有的并发冲突的信息记录下来,而前者只能记录第一个并发冲突的信息。但默认值为FailOnFirstConflict。因为第二种方法原型涉及到了并发冲突,所以在这里将不对第二种方法原型的使用做对应示例,将在之后谈及并发冲突时,在做探讨;

i.调用方法SubmitChanges

SubmitChanges方法
 1 staticvoid Main(string[] args)
2 {
3 string str_conn1 ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
4 DataContext dc4 =new DataContext(str_conn1);
5
6 var student = (from stu in dc4.GetTable<Student>()
7 where stu.No =="20030007"
8 select stu).Single();
9
10 Console.WriteLine("修改前:");
11 Console.WriteLine(student.ToString());
12
13 student.Dept ="电气自动化";
14 dc4.SubmitChanges();
15
16 var student1 = (from stu in dc4.GetTable<Student>()
17 where stu.No =="20030007"
18 select stu).Single();
19
20 Console.WriteLine("修改后:");
21 Console.WriteLine(student1.ToString());
22
23 Console.Read();
24 }

ii.结果

  (2)方法CreateDataBase、DataBaseExists以及DeleteDataBase:

  这三个方法都是针对数据库来操作的,它们的原型都很简单,没有参数,没有返回值,其中方法CreateDataBase可以根据映射信息创建一个数据库,方法DataBaseExists用于判断DataContext对象使用的数据库是否存在,而方法DeleteDataBase用于删除DataContext对象使用的数据库,下面是这三个方法组合使用的示例:

i.映射文件XML:

Mapping.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>

ii.调用方法CreateDataBase和DataBaseExists

方法CreateDataBase和DataBaseExists
 1 string str_conn2 ="Data Source=localhost;Initial Catalog=DB_Student2;User ID=sa;Password=king";
2 XmlMappingSource map1 = XmlMappingSource.FromXml(System.IO.File.ReadAllText(@"Mapping.xml"));
3 DataContext dc5 =new DataContext(str_conn2,map1);
4
5 //创建数据库DB_Student2
6 dc5.CreateDatabase();
7
8 //数据库DB_Student2是否存在
9 bool flag=dc5.DatabaseExists();
10 if (flag)
11 Console.WriteLine("数据库DB_Student2创建成功!");

iii.结果

从结果中可以看到尽管映射文件中含有存储过程和自定义函数的映射信息,但因为没有具体的实现过程,所以单单凭借映射配置文件也只能够创建出相应的物理表。接着我们调用方法DeleteDataBase

iv.调用方法DeleteDataBase和DataBaseExists:

方法DeleteDataBase和DataBaseExists
1 //删除数据库DB_Student2
2 dc5.DeleteDatabase();
3
4 bool flag1 = dc5.DatabaseExists();
5 if (!flag1)
6 Console.WriteLine("数据库DB_Student2删除成功!");

 v.结果

  (3)方法ExecuteQuery、ExecuteCommand:

  方法ExecuteQuery的原型:

  IEnumerable<T> ExecuteQuery<T>(string query, params object[] parameters);

  它用于执行一个带参的SQL查询语句,接收一个带参的查询字符串查询语句query和一个参数数组parameters,返回一个由实体类组成的序列。而方法ExecuteCommand则用于执行一个带参的SQL命令语句,包括插入、修改以及删除操作。它的方法原型:

  int ExecuteCommand(string command, params object[] parameters);

该方法的参数类型与方法ExecuteQuery相同,但返回的则是int类型,表示操作影响的行数。下面是这两个方法的使用示例:

i.调用方法ExecuteQuery和ExecuteCommand

方法ExecuteQuery和ExecuteCommand
 1 string str_conn1 ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2 DataContext dc4 =new DataContext(str_conn1);
3
4 string str_sql =@"select * from student where sage>{0}";
5 var students = dc4.ExecuteQuery<Student>(str_sql, 20);
6
7 Console.WriteLine("年龄大于20岁的学生:");
8 foreach (var stu in students)
9 {
10 Console.WriteLine(stu.ToString());
11 }
12
13 str_sql =@"insert into course(cno,cname,ccredit) values({0},{1},{2})";
14 int rows = dc4.ExecuteCommand(str_sql, newobject[] { "ky030011", "软件工程", 2 });
15 if (rows >0)
16 Console.WriteLine("更新行数:{0}",rows);

ii.结果

  (4)方法GetTable:

  方法原型:

  Table<T> GetTable<T>();

方法GetTable在调用是只需要指定实体类型T即可,DataContext对象会根据指定的实体类信息来查询数据库中相应的物理表,并将记录信息封装成实体类对象放入序列中返回。以下是GetTable方法的使用示例:
i.调用方法GetTable

方法GetTable
 1 string str_conn1 ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2 DataContext dc4 =new DataContext(str_conn1);
3
4 Table<Course> courses = dc4.GetTable<Course>();
5
6 Console.WriteLine("可选课程:");
7 foreach (var c in courses.Select(s =>new {Cno=s.No,Cname=s.Name }).Take(3))
8 {
9 Console.WriteLine(c.ToString());
10 }

ii.结果

  (5)方法Refresh:

  Refresh方法用于根据数据库中的数据更新内存中的实体类对象的状态,在多用户并发访问数据库时,通过该方法可以获取数据库中最新的数据。Refresh方法有三个原型:

  ①void Refresh(RefreshMode mode,object entity);

  ②void Refresh(RefreshMode mode,params object[] entities);

  ③void Refresh(RefreshMode mode,System.Collections.IEnumerable entities);

三个方法原型中都有一个类型为RefreshMode的参数mode,用于指定一个刷新策略。RefreshMode是一个枚举类型,它一共包含三个值KeepChanges、KeepCurrentValues和OverwriteCurrentValues。其中KeepChanges指定方法Refresh保留类对象中已经更改的当前值,将没有更改的属性值更新成数据库中查询到的最新数据。KeepCurrentValues用于指定Refresh方法不更改实体类对象的当前值,但更改实体类对象用于并发访问冲突检测的属性原始值(注:每个实体类对象属性的原始值和当前值都被记住以用于并发访问冲突检测)。而OverwriteCurrentValues则指定方法Refresh把实体类对象中的所有属性都更改为最新的数据库中的值。相比较于前一种,后两种方法原型可以更新多个实体类对象。下面是方法Refresh使用的示例:

i.调用方法Refresh:

方法Refresh
 1 string str_conn1 ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2 DataContext dc4 =new DataContext(str_conn1);
3
4 //Refresh第一个原型:
5 var student2 = dc4.GetTable<Student>().Where(s => s.No =="20030001").Single();
6 Console.WriteLine("在数据库修改之前学号为20030001的学生信息状态:");
7 Console.WriteLine(student2.ToString());
8
9 //修改数据库信息
10 SqlConnection conn =new SqlConnection(str_conn1);
11 SqlCommand cmd = conn.CreateCommand();
12 cmd.CommandText ="update student set sage+=1 where sno='20030001'";
13 cmd.CommandType = System.Data.CommandType.Text;
14 conn.Open();
15 cmd.ExecuteNonQuery();
16 conn.Close();
17
18 dc4.Refresh(RefreshMode.OverwriteCurrentValues, student2);
19
20 Console.WriteLine("在数据库修改之后学号为20030001的学生信息状态:");
21 Console.WriteLine(student2.ToString());
22
23 Console.WriteLine("\n");
24
25 //Refresh第二、三个原型:
26 var course1 = dc4.GetTable<Course>().Where(c => c.Credit >3).Select(c =>new {Cno=c.No,Cname=c.Name,Credit=c.Credit });
27
28 Console.WriteLine("在数据库修改之前学分大于3分的所有课程:");
29 foreach (var c in course1)
30 {
31 Console.WriteLine(c.ToString());
32 }
33
34 //修改数据库信息
35 SqlConnection conn1 =new SqlConnection(str_conn1);
36 SqlCommand cmd1 = conn1.CreateCommand();
37 cmd1.CommandText ="update course set ccredit=ccredit-1 where ccredit>3";
38 cmd1.CommandType = System.Data.CommandType.Text;
39 conn1.Open();
40 cmd1.ExecuteNonQuery();
41 conn1.Close();
42
43 dc4.Refresh(RefreshMode.OverwriteCurrentValues, course1.ToArray());
44 //或dc4.Refresh(RefreshMode.OverwriteCurrentValues, course1.ToList());
45
46 Console.WriteLine("在数据库修改之后学分大于3分的所有课程:");
47 foreach (var c in course1)
48 {
49 Console.WriteLine(c.ToString());
50 }

ii.结果

  (6)方法GetChangeSet:

  GetChangeSet方法用于获取实体类中发生更改的对象集合,因为方法SubmitChanges方法会根据更改的对象集合来生成SQL语句发送给数据库,所以方法GetChangeSet可以获取哪些对象信息将会保存到数据库中去,下面是方法GetChangeSet的原型:

  ChangeSet GetChangeSet();

其中方法原型返回一个ChangeSet对象,该类型定义中包含三个类型为IList<T>的属性(注:T指相应的实体类),分别为Inserts、Updates以及Deletes,这三个属性分别记录相应的在实体类对象状态改变时的操作,所以可以通过列举这三个属性来知道由那些实体类对象被修改。下面是关于方法GetChangeSet使用的示例:

i.调用方法GetChangeSet

方法GetChangeSet
 1 string str_conn1 ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2 DataContext dc4 =new DataContext(str_conn1);
3
4 //更新
5 var course2 = dc4.GetTable<Course>().Where(c => c.Credit ==3);
6 foreach (var c in course2)
7 {
8 c.Credit +=1;
9 }
10
11 //删除
12 var course = dc4.GetTable<Course>().Where(c => c.No =="ky030011").Single();
13 dc4.GetTable<Course>().DeleteOnSubmit(course);
14
15 //插入
16 Student student3 =new Student() { No ="20030011", Name ="小六", Dept ="汉语", Sex ="", Age =23};
17 dc4.GetTable<Student>().InsertOnSubmit(student3);
18
19 //获取所有实体类对象更改信息
20 ChangeSet cs = dc4.GetChangeSet();
21
22 Console.WriteLine("发生更新的实体类对象:");
23 foreach (var c in cs.Updates)
24 {
25 Console.WriteLine(c.ToString());
26 }
27
28 Console.WriteLine("发生删除操作的实体类对象:");
29 foreach (var c in cs.Deletes)
30 {
31 Console.WriteLine(c.ToString());
32 }
33
34 Console.WriteLine("发生新增操作实体类对象:");
35 foreach (var s in cs.Inserts)
36 {
37 Console.WriteLine(s.ToString());
38 }
39
40 dc4.SubmitChanges();
41
42 Console.Read();

ii.结果

  3.DataContext成员属性:

  (1)属性Log:

  在DataContext类中最重要的属性就属于Log了,它用于输出对象DataContext和数据库通信时使用的SQL语句信息。DataContext对象负责将实体类的更改转换成SQL语句发送给数据库,而这些SQL语句的信息保存在Log属性里,可以根据属性内容进行调试、以及优化。属性Log的类型为System.IO.TextWriter,使用时只需要指定一个TextWriter对象给它就OK了。下面是有关Log属性使用的示例:

i.Log属性使用

属性Log
 1 string str_conn1 ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2 DataContext dc4 =new DataContext(str_conn1);
3
4 //输出SQL语句到控制台窗口
5 dc4.Log = Console.Out;
6
7 var students1 = dc4.GetTable<Student>().Where(s=>s.Age>22);
8 foreach(var stu in students1)
9 {
10 stu.Age +=1;
11 }
12
13 dc4.SubmitChanges();
14
15 Console.Read();

ii.结果

  4.DataContext的服务功能:

  (1)实体跟踪服务:

  实体跟踪服务英译过来称为Identity Tracking,又称标识跟踪。它的服务功能在于当第一次从数据库中查询数据时,这份数据的主键信息和由此数据生成的实体类对象就被缓存进DataContext对象,当后续再次向数据库查询此数据时,DataContext对象先检测缓存中是否有对应的实体类对象存在。如果缓存中有,则将缓存中的对应实体类对象返回,而不是再次查询数据库。只有当缓存中不存在对应实体类对象,才会去重新查询数据库。那么这项服务功能有何意义呢?当多用户并发访问数据库时,一个用户对数据库中同一条记录的拷贝实体类对象的修改,且直到修改提交到数据库,这整个过程都不会影响其他用户对数据库中同一条记录的拷贝实体类对象的修改情况。下面用示例来进一步说明:

i.模拟多用户并发访问

实体跟踪服务
 1 string str_sql ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2
3 //模拟多用户并发访问
4 DataContext dc =new DataContext(str_sql);
5 DataContext dc1 =new DataContext(str_sql);
6
7 var student = dc.GetTable<Student>().Where(s => s.No =="20030008").Single();
8 Console.WriteLine(student.ToString());
9 var student2 = dc1.GetTable<Student>().Where(s => s.No =="20030008").Single();
10 Console.WriteLine(student2.ToString());
11
12 //修改实体类对象
13 student.Name ="苗翠花";
14 student.Age=23;
15 student.Sex="";
16
17 //向数据库提交修改
18 dc.SubmitChanges();
19
20 var student1 = dc.GetTable<Student>().Where(s => s.No =="20030008").Single();
21 Console.WriteLine(student1.ToString());
22 var student3 = dc1.GetTable<Student>().Where(s => s.No =="20030008").Single();
23 Console.WriteLine(student3.ToString());
24
25 Console.Read();

ii.结果

  (2)更改跟踪服务:

  更改跟踪服务英译过来称为Change Tracking,它DataContext对象提供的另外一种服务功能。自从DataContext对象查询数据库生成实体类对象开始便启动了实体跟踪服务,且跟踪服务一直跟踪实体类对象的所有更改信息,直到DataContext对象把该实体类对象提交修改到数据库中(即执行SubmitChanges方法)为止。DataContext对象通过保存实体类对象的第一次查询值(即对象原始值)和当前值的方法来实现跟踪服务。当调用SubmitChanges方法时,DataContex对象就会比较原始值和当前值,如果它们不同,那么就会产生必要的SQL语句,并在数据库执行。然后把当前值作为实体类对象的新的原始值,继续新的跟踪服务。但是,当一个实体类对象不是由DataContex对象产生时,DataContext对象就无法知道该实体类对象的存在,也就无法对该实体类对象实行实体跟踪服务了,但这个时候可以在DataContext对象的方法GetTable返回值Table<T>里添加进这个实体类对象,那么DataContext就对该实体类对象提供跟踪服务了。下面用示例说明:

i.为实体类对象提供跟踪服务

为实体类对象course提供跟踪服务
 1 string str_sql ="Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
2 DataContext dc =new DataContext(str_sql);
3
4 Course course =new Course()
5 {
6 No="ky030011",
7 Name="软件工程",
8 Credit=2,
9 };
10
11 //为实体类对象course提供跟踪服务
12 dc.GetTable<Course>().InsertOnSubmit(course);
13
14 dc.SubmitChanges();
15
16 Console.Read();

ii.结果

posted @ 2011-09-12 12:27  Rookie_J  阅读(3239)  评论(0编辑  收藏  举报