在EntityFramework for MySql中设置提供程序和连接字符串

时间:2014-09-01 08:42:23

标签: c# mysql entity-framework

我正在使用实体框架,在我的解决方案中有9个项目,它将会扩大。我的问题是在.config文件中声明连接字符串。当我这样做时,我必须为4-5个项目声明连接字符串,当我想要更改我的连接时,更改ConnectionStrings将成为4或5个项目的义务。我想在DbContext构造函数中设置连接字符串。 DbContext可以为我提供这种能力,但我无法定义providerName.So上下文的dbconnection自动使用SqlClient但我想使用MySql提供程序。我的连接字符串是:

"Server=localhost;Database=xxx;Uid=auth_windows;Persist Security Info=True;User=root;Password=yyyyyy;"

此外,我无法在连接字符串中指定提供程序名称,如“Provider = MySql.Data.MySqlClient”。它抛出异常“不支持Provider关键字”。

我正在改变我的问题,以便更容易理解。

总之我想要这个。

public class XxContext : DbContext
{

       public XxContext()
       {

            this.Database.Connection.Provider = "MySql.Data.MySqlClient";
            this.Database.Connection.ConnectionString = "Server=localhost bla bla bla";

       }
}

但我不知道如何声明你应该使用MySql.Data.MySqlClient(没有配置文件)。可能吗 ?如果是,我该怎么办?

3 个答案:

答案 0 :(得分:4)

你的是connection string used with SqlConnection objects。由于这些对象仅支持SQL Server,因此您无法使用Provider关键字。此外,由于您使用的是EF,因此需要指定不同的连接字符串才能使用数据库模型,上下文和Provider关键字。典型的EF connection string将是:

<connectionStrings>
    <add name="AdventureWorksEntities" 
         connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
         provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
         Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
         multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />
</connectionStrings>

要使用MySQL提供程序,请考虑this answer中提供的这些步骤:

  

实体框架6提供了一些方便的微妙变化,有助于两者   让MySQL工作并创建动态数据库连接。   让MySQL使用Entity Framework 6

     

首先,在我回答这个问题之日,唯一的.Net   与EF6兼容的连接器驱动程序是MySQL .Net Connectior   6.8.1(Beta开发版),可在MySQL官方网站上找到。

     

安装后,从Visual引用以下文件   工作室解决方案:

Mysql.Data.dll
Mysql.Data.Entity.EF6.dll
     

您还需要将这些文件复制到原处   在构建期间可以访问项目,例如bin   。目录

     

接下来,您需要向Web.config(或者如果是App.config)添加一些项目   基于桌面的文件。

     

连接字符串:

<connectionStrings>
    <add name="mysqlCon"
         connectionString="Server=localhost;Database=dbName;Uid=username;Pwd=password"

         providerName="MySql.Data.MySqlClient" /> </connectionStrings>
  

还可以选择在和节点内部添加提供程序(这是绝对必须在第二部分   我的答案,在处理动态定义的数据库时)你可以   改变节点:

<entityFramework>
    <defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" />
    <providers>
        <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
    </providers> </entityFramework>
  

如果从默认的sql server更改defaultConnectionFactory   连接,不要忘记删除哪些节点   嵌套在defaultConnectionFactory节点中。该   MysqlConnectionFactory不为其采用任何参数   如果参数仍然存在,构造函数将失败。

答案 1 :(得分:2)

您可以使用配置文件中注册的DbProviderFacory(请参阅MSDNSO article)。

你的配置文件应该有这样的东西

<DbProviderFactories>
  <remove invariant="MySql.Data.MySqlClient" />
  <add name="MySQL Data Provider"
       invariant="MySql.Data.MySqlClient"
       description=".Net Framework Data Provider for MySQL"
       type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>

您的DbContextIDbContextFactory实现类似于此......

<强>的DbContext

public class MyDbContext
    : DbContext
{
    public MyDbContext(DbConnection connection, bool contextOwnsConnection)
        : base(connection, contextOwnsConnection)
    {

    }
}

<强> IDbContextFactory

public class MyDbContextFactory
    : IDbContextFactory<MyDbContext>
{
    private readonly string _connectionStringName;

    public MyDbContextFactory(string connectionStringName)
    {
        Contract.Requires<NullReferenceException>(
            !string.IsNullOrEmpty(connectionStringName),
            "connectionStringName");
        _connectionStringName = connectionStringName;
    }

    public MyDbContext Create()
    {
        var connectionStringSettings = ConfigurationManager
            .ConnectionStrings[_connectionStringName];

        var connection = DbProviderFactories
            .GetFactory(connectionStringSettings.ProviderName)
            .CreateConnection();

        if (connection == null)
        {
            var message = string.Format(
                "Provider '{0}' could not be used",
                connectionStringSettings.ProviderName);
            throw new NullReferenceException(message);
        }

        connection.ConnectionString = connectionStringSettings
            .ConnectionString;
        return new MyDbContext(connection, true);
    }
}

与上下文构造函数的连接能够以编程方式包含DbProvider。上下文设置为拥有连接,以便它可以在首次使用时打开并在关闭时关闭。

答案 2 :(得分:0)

有几种设置提供程序的方法,但我认为最简单的方法是在DbContext类中添加一个属性。然后将完整的连接字符串传递给其构造函数。构造一个MySqlConnection对象,并将其传递给DbContext构造函数。请参阅下面的EF6示例代码;

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /api/ {
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-NginX-Proxy           true;
                proxy_pass              http://localhost:5000;
                proxy_set_header        Host                    $http_host;
                proxy_cache_bypass      $http_upgrade;
                proxy_redirect          off;
        }

        error_page 404 /404.html;
                location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
                location = /50x.html {
        }
    }

}