EF 数据库链接约定(Connection String Conventions in Code First)

一个典型的EF应用大多数状况下是一个DbContext的派生类(derived class)来控制,一般可使用该派生类调用DbContext的构造函数,来控制如下的东西:web

(1)、上下文如何链接到数据库(给定链接字符串)sql

(2)、上下文是经过Code First语法计算模型仍是使用EF 设计器数据库

(3)、额外的高级选项服务器

下面是DbContext构造器的经常使用的用途:app

1、DbContext无参构造函数less

若是当前EF应用中没有作任何的配置.且在你自定义的数据库上下文类中没有调用DbContext带参的构造函数,那么当前应用对应的数据库上下文类,将会调用DbContext的默认无参的构造函数(EF默认规定的数据库链接),代码以下:ide

namespace Demo.EF 
{ 
    public class EFStudyContext : DbContext 
    { 
        public EFStudyContext()// C# will call base class parameterless constructor by default 
        { 
        } 
    } 
}

 

EF默认的联结字符串以下:函数

Data Source=(localdb)\mssqllocaldb;Initial Catalog=EFStudyConsole(项目名称).EFStudyDbContext(上下文名称);Integrated Security=True;MultipleActiveResultSets=True

 

EF会用上下文的彻底限定名(命名空间+上下文类)做为数据库名,建立一个链接字符串,该链接字符串会链接本地的SQL Express或者LocalDb,并在SQL Express或者LocalD建立对应的数据库,若是二者都安装了,则会选择链接SQL Express。ui

注:VS2010默认安装SQL Express,VS2012默认安装LocalDb,在安装过程当中,EF NuGet包会检查哪一个数据库服务(前面介绍的)可用,当EF建立默认链接的时候,当EF建立默认连接的时候,NuGet包将经过设置默认的Code First数据库服务器来更新配置文件,该数据库服务器在经过约定建立链接时首先使用该服务器。.若是SQL Express 正在运行,它会被使用,若是它不可用,LocalDb会替代它,可是这个过程不会对配置文件作任何的更改,若是它已经包含默认链接工厂的设置.spa

 

2、DbContext带string参数的构造函数

一、若是没有在数据库上下文进行其余额外的配置,而后调用DbContext中的带参的构造函数,传入你想要使用的数据库链接字符串,而后Code First中的数据库上下文就会运行在基于当前数据库链接字符串上.代码以下:

public class BloggingContext : DbContext 
{ 
    public BloggingContext(): base("BloggingDatabase") 
    {} 
}
Data Source=(localdb)\mssqllocaldb;Initial Catalog=BloggingDatabase;Integrated Security=True;MultipleActiveResultSets=True

 

二、使用app.config/web.config配置文件中的链接字符串,表示你在应用程序中已经进行了配置,这一点要区分上面的方法.

(1)、有Ado.Net使用经历的都知道,通常状况下,数据库链接字符串通常定义在app.config/web.config配置文件中,例如:

<configuration> 
  <connectionStrings> 
    <add name="BolggingContext" 
         providerName="System.Data.SqlServerCe.4.0" 
         connectionString="Data Source=Blogging.sdf"/> 
  </connectionStrings> 
</configuration>

这在EF中至关于告诉数据库上下文去使用当前链接字符串对应的数据库服务,而不是使用SQL Express or LocalDb,数据库上下文代码以下:

public class BloggingContext : DbContext 
{ 
    public BloggingContext()
    { 
    } 
}

若是链接字符串的name属性值和上下文类名同样(either with or without namespace qualification),那么数据库上下文在执行无参构造函数的时候,会使用配置文件的链接字符串去链接数据库.

using (var context=new BloggingContext())
{
     string connStr = context.Database.Connection.ConnectionString;
     Console.WriteLine(connStr);
}   

 

(2)、若是链接字符串的name属性值和上下文类名不同,可是仍是但愿上下文使用配置文件的数据库链接进行数据库链接,这时就须要在上下文构造函数中调用DbContext的带string参数的构造函数,并传入链接字符串的name属性值,代码以下:

    public class BloggingContext:DbContext
    {
        public DbSet<User> Users { get; set; }

        public BloggingContext():base("BloggingStr")
        {

        }
    }
    static void Main(string[] args)
    {
         using (var context=new BloggingContext())
         {
             string connStr = context.Database.Connection.ConnectionString;
             Console.WriteLine(connStr);
         }
         Console.ReadKey();
    }

另一种方式是传递给DbContext构造函数配置文件中的connectionString节点的name属性来指定上下文经过配置文件中connectionString来链接字符串,代码以下:

    public class BloggingContext:DbContext
    {
        public DbSet<User> Users { get; set; }

        public BloggingContext():base("name=BloggingStr")
        {

        }
    }
    static void Main(string[] args)
    {
        using (var context=new BloggingContext())
        {
            string connStr = context.Database.Connection.ConnectionString;
            Console.WriteLine(connStr);
        }
        Console.ReadKey();
    }

上面这种方式是明确EF进行数据库链接的时候去配置文件找链接字符串。

(3)、链接字符串的终极解决方案,直接给链接字符串,什么都不要配,代码以下:

    public class BloggingContext:DbContext
    {
        public DbSet<User> Users { get; set; }

        public BloggingContext():base("server=.;database=EFStudy;uid=sa;pwd=123456;")
        {

        }
    }
    static void Main(string[] args)
    {
         using (var context=new BloggingContext())
         {
             string connStr = context.Database.Connection.ConnectionString;
              Console.WriteLine(connStr);
          }
          Console.ReadKey();
     }

注:默认状况下,当前的链接字符串使用的是System.Data.SqlClilent做为provider,这里能够被改变经过作一个IConnectionFactory的不一样的实现来替换context.Database.DefaultConnectionFactory默认的实现.

 

3、还有其余两种方法,不经常使用

一、You can use an existing DbConnection object by passing it to a DbContext constructor. If the connection object is an instance of EntityConnection, then the model specified in the connection will be used rather than calculating a model using Code First. If the object is an instance of some other type—for example, SqlConnection—then the context will use it for Code First mode.

使用一个DbConnection 实例,或者是SqlConnection实例或者EntityConnection实例,传递给DbContext的构造函数都可指定对应的数据库链接规则.

 

二、You can pass an existing ObjectContext to a DbContext constructor to create a DbContext wrapping the existing context. This can be used for existing applications that use ObjectContext but which want to take advantage of DbContext in some parts of the application.