LINQ to SQL语句(22)之DataContext

来源:互联网 发布:怎么用excel筛选数据 编辑:程序博客网 时间:2024/04/29 19:48

http://www.prg-cn.com/article-4431-1.html

DataContext

DataContext作为LINQ to SQL框架的主入口点,为我们 提供了一些方法和属性,本文用几个例子说明DataContext几个典型的应用。

创建和删除数据库

CreateDatabase方法用于在服务器上创建数据库。

DeleteDatabase方法用于删除由DataContext连接字符串标识的数据 库。

数据库的名称有以下方法来定义:

如果数据库在连接字符串 中标识,则使用该连接字符串的名称。

如果存在DatabaseAttribute属性 (Attribute),则将其Name属性(Property)用作数据库的名称。

如果连接 字符串中没有数据库标记,并且使用强类型的DataContext,则会检查与 DataContext继承类名称相同的数据库。如果使用弱类型的DataContext,则会引 发异常。

如果已通过使用文件名创建了DataContext,则会创建与该文件 名相对应的数据库。

我们首先用实体类描述关系数据库表和列的结构的 属性。再调用DataContext的CreateDatabase方法,LINQ to SQL会用我们的定义 的实体类结构来构造一个新的数据库实例。还可以通过使用 .mdf 文件或只使用 目录名(取决于连接字符串),将 CreateDatabase与SQL Server一起使用。 LINQ to SQL使用连接字符串来定义要创建的数据库和作为数据库创建位置的服 务器。

说了这么多,用一段实例说明一下吧!

首先,我们新建一 个NewCreateDB类用于创建一个名为NewCreateDB.mdf的新数据库,该数据库有一 个Person表,有三个字段,分别为PersonID、PersonName、Age。

  1. public class NewCreateDB : DataContext
  2. {
  3.   public Table<Person> Persons;
  4.   public NewCreateDB (string connection)
  5.     :
  6.     base(connection)
  7.   {
  8.   }
  9.   public NewCreateDB(System.Data.IDbConnection connection)
  10.     :
  11.     base(connection)
  12.   {
  13.   }
  14. }
  15. [Table(Name = "Person")]
  16. public partial class Person : INotifyPropertyChanged
  17. {
  18.   private int _PersonID;
  19.   private string _PersonName;
  20.   private System.Nullable<int> _Age;
  21.   public Person() { }
  22.    [Column(Storage = "_PersonID", DbType = "INT",
  23.     IsPrimaryKey = true)]
  24.   public int PersonID
  25.   {
  26.     get { return this._PersonID; }
  27.     set
  28.     {
  29.       if ((this._PersonID != value))
  30.       {
  31.          this.OnPropertyChanged("PersonID");
  32.          this._PersonID = value;
  33.         this.OnPropertyChanged ("PersonID");
  34.       }
  35.     }
  36.   }
  37.   [Column(Storage = "_PersonName", DbType = "NVarChar(30)")]
  38.   public string PersonName
  39.    {
  40.     get { return this._PersonName; }
  41.     set
  42.     {
  43.       if ((this._PersonName != value))
  44.        {
  45.         this.OnPropertyChanged ("PersonName");
  46.         this._PersonName = value;
  47.         this.OnPropertyChanged ("PersonName");
  48.       }
  49.     }
  50.    }
  51.   [Column(Storage = "_Age", DbType = "INT")]
  52.   public System.Nullable<int> Age
  53.   {
  54.     get { return this._Age; }
  55.     set
  56.      {
  57.       if ((this._Age != value))
  58.        {
  59.         this.OnPropertyChanged("Age");
  60.         this._Age = value;
  61.          this.OnPropertyChanged("Age");
  62.       }
  63.      }
  64.   }
  65.   public event PropertyChangedEventHandler PropertyChanged;
  66.   protected virtual void OnPropertyChanged (string PropertyName)
  67.   {
  68.     if ((this.PropertyChanged != null))
  69.     {
  70.        this.PropertyChanged(this,
  71.         new PropertyChangedEventArgs(PropertyName));
  72.     }
  73.   }
  74. }
复制代码

接下来的一段代码先创建一个数据库,在调用 CreateDatabase后,新的数据库就会存在并且会接受一般的查询和命令。接着插 入一条记录并且查询。最后删除这个数据库。

  1. //1.新建一个临时 文件夹来存放新建的数据库
  2. string userTempFolder = Environment.GetEnvironmentVariable
  3. ("SystemDrive") + @"\YJingLee";
  4. Directory.CreateDirectory (userTempFolder);
  5. //2.新建数据库NewCreateDB
  6. string userMDF = System.IO.Path.Combine(userTempFolder,
  7.   @"NewCreateDB.mdf");
  8. string connStr = String.Format (@"Data Source=.\SQLEXPRESS;
  9. AttachDbFilename={0};Integrated Security=True;
  10. Connect Timeout=30;User Instance=True;
  11. Integrated Security = SSPI;", userMDF);
  12. NewCreateDB newDB = new NewCreateDB(connStr);
  13. newDB.CreateDatabase();
  14. //3.插入 数据并查询
  15. var newRow = new Person
  16. {
  17.    PersonID = 1,
  18.    PersonName = "YJingLee",
  19.    Age = 22
  20. };
  21. newDB.Persons.InsertOnSubmit(newRow);
  22. newDB.SubmitChanges();
  23. var q = from x in newDB.Persons
  24.       select x;
  25. //4.删除数据库
  26. newDB.DeleteDatabase();
  27. //5.删除临时目录
  28. Directory.Delete (userTempFolder);
复制代码

数据库验证

DatabaseExists方法用于 尝试通过使用DataContext中的连接打开数据库,如果成功返回true。

下 面代码说明是否存在Northwind数据库和NewCreateDB数据库 。

  1. // 检测Northwind数据库是否存在
  2. if (db.DatabaseExists())
  3.    Console.WriteLine("Northwind数据库存在");
  4. else
  5.    Console.WriteLine("Northwind数据库不存在");
  6. //检测 NewCreateDB数据库是否存在
  7. string userTempFolder = Environment.GetEnvironmentVariable("Temp");
  8. string userMDF = System.IO.Path.Combine(userTempFolder,
  9. @"NewCreateDB.mdf");
  10. NewCreateDB newDB = new NewCreateDB(userMDF);
  11. if (newDB.DatabaseExists())
  12.    Console.WriteLine("NewCreateDB数据库存在");
  13. else
  14.   Console.WriteLine("NewCreateDB数据库不存在 ");
复制代码

数据库更改

SubmitChanges方法计算要插入、更 新或删除的已修改对象的集,并执行相应命令以实现对数据库的更改。

无论对象做了多少项更改,都只是在更改内存中的副本。并未对数据库中的实际 数据做任何更改。直到对DataContext显式调用SubmitChanges,所做的更改才会 传输到服务器。调用时,DataContext会设法将我们所做的更改转换为等效的SQL 命令。我们也可以使用自己的自定义逻辑来重写这些操作,但提交顺序是由 DataContext的一项称作“更改处理器”的服务来协调的。事件的顺 序如下:

当调用SubmitChanges时,LINQ to SQL会检查已知对象的集合 以确定新实例是否已附加到它们。如果已附加,这些新实例将添加到被跟踪对象 的集合。

所有具有挂起更改的对象将按照它们之间的依赖关系排序成一 个对象序列。如果一个对象的更改依赖于其他对象,则这个对象将排在其依赖项 之后。

在即将传输任何实际更改时,LINQ to SQL会启动一个事务来封装 由各条命令组成的系列。

对对象的更改会逐个转换为SQL命令,然后发送 到服务器。

如果数据库检测到任何错误,都会造成提交进程停止并引发 异常。将回滚对数据库的所有更改,就像未进行过提交一样。DataContext 仍具 有所有更改的完整记录。

下面代码说明的是在数据库中查询CustomerID 为ALFKI的顾客,然后修改其公司名称,第一次更新并调用SubmitChanges()方法 ,第二次更新了数据但并未调用SubmitChanges()方法。

  1. //查询
  2. Customer cust = db.Customers.First(c => c.CustomerID == "ALFKI");
  3. //更新数据并调用SubmitChanges()方法
  4. cust.CompanyName = "YJingLee's Blog";
  5. db.SubmitChanges();
  6. //更新数据没有调用SubmitChanges()方法
  7. cust.CompanyName = "http://lyj.cnblogs.com";
复制代码

动态查询

使用动态查询,这个例子用CreateQuery()方法创建一个 IQueryable<T>类型表达式输出查询的语句。这里给个例子说明一下。有 关动态查询具体内容,下一篇介绍。

  1. var c1 = Expression.Parameter(typeof(Customer), "c");
  2. PropertyInfo City = typeof(Customer).GetProperty ("City");
  3. var pred = Expression.Lambda<Func<Customer, bool>>(
  4.    Expression.Equal(
  5.   Expression.Property(c1, City),
  6.    Expression.Constant("Seattle")
  7.   ), c1
  8. );
  9. IQueryable custs = db.Customers;
  10. Expression expr = Expression.Call(typeof(Queryable), "Where",
  11.   new Type[] { custs.ElementType }, custs.Expression, pred);
  12. IQueryable<Customer> q = db.Customers.AsQueryable().
  13. Provider.CreateQuery<Customer>(expr);
复制代码

日志

Log属性用于将SQL查询或命令打印到TextReader。此方法对了解 LINQ to SQL 功能和调试特定的问题可能很有用。

下面的示例使用Log属性在 SQL代码执行前在控制台窗口中显示此代码。我们可以将此属性与查询、插入、 更新和删除命令一起使用。

  1. //关闭日志功能
  2. //db.Log = null;
  3. //使用日志功能:日志输出到控制台窗口
  4. db.Log = Console.Out;
  5. var q = from c in db.Customers
  6.     where c.City == "London"
  7.     select c;
  8. //日志输出到 文件
  9. StreamWriter sw = new StreamWriter(Server.MapPath ("log.txt"), true);
  10. db.Log = sw;
  11. var q = from c in db.Customers
  12.     where c.City == "London"
  13.      select c;
  14. sw.Close();
复制代码

原创粉丝点击