Code First04---关于上下文DbContext
这章主要讲怎么配置DbContext的子类访问的数据库的位置。
我相信大家最经常使用的数据库位置的配置方式就是配置文件了,也就是通过App.Config 或Web.Config来配置要访问的数据库。我们可以再配置文件里添加一个连接字符串的配置来定义数据库的位置
<connectionStrings>
<add name="OrderSystemContext" connectionString="Data Source=XXX\SQL2008R2;Initial Catalog=OrderSystem;User Id=XXX;Password=XXX" providerName="System.Data.SqlClient"/>
</connectionStrings>
那么怎么样Code First知道使用哪个连接字符串来找到要访问的数据库呢?
默认情况下,DbContext 会找继承上下文子类的同名的连接字符串。
有一个简单的方式,如果你想使用固定的连接字符串的名字而不是通过参数把名字传进来,可以直接在默认构造函数中调用基类的构造函数,传入固定的连接字符串名称:
public OrderSystemContext()
:base("OrderSystem")
{
}
如果我们程序中同时存在多个DbContext的子类的时候,Entity Framework会为每个DbContext的子类都创建一个数据库连接,那么我们的程序就保留了很多个数据库连接的实例。如果我们要优化我们的程序,就可以让多个DbContext子类使用同一个数据库连接实例。我们还是要通过重载DbContext的另一个构造函数来实现这个功能。
public OrderSystemContext(DbConnection connection, bool contextOwnsConnection)
: base(connection, contextOwnsConnection){
}
这个构造函数有两个参数,第一个是我们共用的上下文实例,第二个参数是个开关,用于控制是否由当前的DbContext子类控制数据库连接实例。
如果contextOwnsContext属性为true,那么当DbContext子类Dispose的时候,就会把共用的DbConnection实例也Dispose掉。如果这个值是false,则数据库连接实例就需要由程序员自己写程序释放。string connectionString = @"Data Source=XXX\SQL2008R2;Initial Catalog=OrderSystem;User Id=XXX;Password=XXX";
SqlConnection conn = new SqlConnection(connectionString);OrderSystemContext unitOfWork = new OrderSystemContext(conn,true);
ProductRepository repository = new ProductRepository(unitOfWork);
ProductCatalog catalog = repository.SearchProductCatalog(c => c.CatalogName == "DELL E6400", 1, 10)[0];
Product product = new Product { Catalog = catalog, CreateDate = DateTime.Parse("2010-2-10"), ExpireDate = DateTime.Parse("2012-2-10") };
repository.AddNewProduct(product);
unitOfWork.CommitChanges();
EF会通过一个实现了IDbConnectionFactory接口的类为我们自定义的DbContext类创建数据库连接。Entity Framework默认提供一个SqlConnectionFactory类用来创建SQL Server的数据库连接。Entity Framework Code First中Database.DefaultConnectionFactory属性存储就是SqlConnectionFactory的对象。
你可以初始化一个新的SqlConnectionFactory的实例,把它赋给Database.DefaultConnectionFactory属性,你还可以在初始化SqlConnectionFactory的时候,将一些数据库配置传进去覆盖Code First的默认数据库连接配置。