DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修改写入数据库。
DataContext提供了以下一些使用的功能:
- 以日志形式记录DataContext生成的SQL
- 执行SQL(包括查询和更新语句)
- 创建和删除数据库
DataContext是实体和数据库之间的桥梁,那么首先我们需要定义映射到数据表的实体。
定义实体类
- [Table(Name = "tb_Students")]
- public class Student
- {
- [Column(IsPrimaryKey = true)]
- public int stuId { get; set; }
- [Column(Name = "stuName")]
- public string stuName { get; set; }
- [Column]
- public int stuAge { get; set; }
- }
以TempDBS数据库为例,上述Student类被映射成一个表,对应数据库中的 tb_Students表。然后在类型中定义了三个属性,对应表中的三个字段。其中,stuId字段是主键,如果没有指定Column特性的Name属性,那么系统会把属性名作为数据表的字段名,也就是说实体类的属性名就需要和数据表中的字段名一致。
现在,创建一个WinForm窗体,然后在窗体上加入一个DataGridView控件,使用下面的代码进行绑定数据:
- DataContext dc = new DataContext("Data Source=.;Initial Catalog=TempDBS;User ID=sa;Password=liufenghua");
- public FormApp()
- {
- InitializeComponent();
- Table<Student> stuAll = dc.GetTable<Student>();
- dataGridView1.DataSource = from stu in stuAll
- where stu.stuId == 1
- select new { id = stu.stuId,name=stu.stuName,age=stu.stuAge };
- }
使用DataContext类型把实体类和数据库中的数据进行关联。你可以直接在DataContext的构造方法中定义连接字符串,也可以使用IDbConnection:
- IDbConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TempDBS;User ID=sa;Password=liufenghua");
- DataContext dc = new DataContext(conn);
- Table<Student> stuAll = dc.GetTable<Student>();
- dataGridView1.DataSource = from stu in stuAll
- where stu.stuId == 1
- select new { id = stu.stuId,name=stu.stuName,age=stu.stuAge };
之后,通过GetTable获取表示底层数据表的Table类型,显然,数据库中的tb_Students表的实体是Student类型。随后的查询句法,即使你不懂SQL应该也能看明白。从tb_Students
表中找出stuId等于1的记录,并把stuid,stuName以及stuAge封装成新的匿名类型进行返回。
强类型DataContext
- public partial class NorthwindDataContext :DataContext
- {
- public Table<Student> Students;
- public NorthwindDataContext(IDbConnection connection) : base(connection) { }
- public NorthwindDataContext(string connection) : base(connection) { }
- }
强类型数据上下文使代码更简洁:
- NorthwindDataContext dc = new NorthwindDataContext("Data Source=.;Initial Catalog=TempDBS;User ID=sa;Password=liufenghua");
- dataGridView1.DataSource = from stu in dc.Students
- where stu.stuId == 1
- select new { id = stu.stuId,name = stu.stuName,age = stu.stuAge };
日志功能
- NorthwindDataContext dc = new NorthwindDataContext("Data Source=.;Initial Catalog=TempDBS;User ID=sa;Password=liufenghua");
- StreamWriter sw = new StreamWriter(Application.StartupPath+"\\log.txt",true); //追加日记数据
- dataGridView1.DataSource = from stu in dc.Students
- where stu.stuId == 1
- select new { id = stu.stuId,name = stu.stuName,age = stu.stuAge };
- sw.Close();
- sw.Dispose();
运行程序后在项目所在目录生成了log.txt,每次查询都会把诸如下面的日志追加到文本文件中:
SELECT [t0].[stuId] AS [id], [t0].[stuName] AS [name], [t0].[stuAge] AS [age]
FROM [tb_Students] AS [t0]
WHERE [t0].[stuId] = @p0
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1
探究查询
- NorthwindDataContext dc = new NorthwindDataContext("Data Source=.;Initial Catalog=TempDBS;User ID=sa;Password=liufenghua");
- var select = from stu in dc.Students
- where stu.stuId == 1
- select new { id = stu.stuId,name = stu.stuName,age = stu.stuAge };
- IDbCommand cmd = dc.GetCommand(select);
- Console.Write(cmd.CommandText);
- foreach(DbParameter parm in cmd.Parameters)
- {
- Console.Write(string.Format("参数名:{0},参数值:{1}",parm.ParameterName,parm.Value));
- }
- Student stus = dc.Students.First();
- stus.stuName = "刘华";
- IList<object> queryText = dc.GetChangeSet().Updates;
- Console.Write(((Student)queryText[0]).stuName);
在这里,我们通过DataContext的GetCommand方法获取了查询对应的DbCommand,并且输出了CommandText和所有的DbParameter。之后,我们又通过GetChangeSet方法获取了修改后的实体,并输出了修改内容。
执行查询
- NorthwindDataContext dc = new NorthwindDataContext("Data Source=.;Initial Catalog=TempDBS;User ID=sa;Password=liufenghua");
- string newName = "刘华";
- dc.ExecuteCommand("update tb_Students set stuName={0} where stuId=1",newName);
- IEnumerable<Student> student = dc.ExecuteQuery<Student>("select * from tb_Students where stuId=1");
- dataGridView1.DataSource = student;
虽然Linq to sql能实现90%以上的TSQL功能。但是不可否认,对于复杂的查询,使用TSQL能获得更好的效率。因此,DataContext类型也提供了执行SQL语句的能力。
转载于:https://blog.51cto.com/3302026/1108743