Art*_*nin 11 mysql sql-server entity-framework-6
昨天我做了一个Web应用程序的迁移(EF 5.0 => EF 6.0),它使用实体框架来访问MySql和SQL Server数据库(特别DbContext是特定数据库,而不是DbContext任何类型的数据库).
编译时间没有任何问题,运行时遇到异常:
在发现"MySqlEFConfiguration"类型之前,实体框架使用了默认的DbConfiguration实例.
[DbConfigurationType(typeof(MySqlEFConfiguration))]上下文中的属性似乎在运行时被忽略,因为上下文位于外部程序集(?)中,而DbConfigurationused对应用程序域是全局的,而不是上下文(?)的特定内容.
我尝试了不同的方法来解决它,然后谷歌搜索它 - 惊喜 - 找不到有效的解决方案.
貌似情况描述在这里形成良好http://forums.mysql.com/read.php?174,614148,614148仍未改变,或者我错过了一些明显的事情.
任何反馈将不胜感激.
先感谢您!
详细说明:
输入(简化): - ASP.NET Web应用程序
通过Entity Framework 6.1.1实现的数据访问层
实体框架提供者:
System.Data.SqlClient 6.1.1
MySql.Data.MySqlClient 6.9.4
MY_SqlContext,模型第一个概念,针对MY SQL Server数据库
Ms_SqlContext,数据库第一个概念,针对MS SQL Server数据库
根据Entity Framework 6和MySql Connector/Net文档(http://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html)的通用文档,MY_SqlContext需要应用MySqlEFConfiguration.
根据上面提到的两个文件,有三种选择可以做到这一点.这三个人都经过了尝试而失败了
选项1:将DbConfigurationTypeAttribute添加[DbConfigurationType(typeof(MySqlEFConfiguration))]到MY_SqlContext类
适当的Web.config段:
<connectionStrings>
<add name="MY_SqlContext"
connectionString="server=.;User Id=root;password=...;Persist Security Info=True;database=MySqlDb;Use Compression=False;Use Old Syntax=False"
providerName="MySql.Data.MySqlClient" />
<add name="Ms_SqlContext"
connectionString="metadata=res://*/Ms_SqlContext.csdl|res://*/Ms_SqlContext.ssdl|res://*/Ms_SqlContext.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=MsSqlDb;User ID=appuser;Password=...""
providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
Run Code Online (Sandbox Code Playgroud)
应用程序启动后,Web请求开始处理:
Ms_SqlContext工作正常,但尝试创建一个MY_SqlContext实例,我得到异常:
在发现"MySqlEFConfiguration"类型之前,实体框架使用了默认的DbConfiguration实例.必须在应用程序启动时设置"MySqlEFConfiguration"实例,然后才能使用任何Entity Framework功能,或者必须在应用程序的配置文件中注册.有关详细信息,请参阅... LinkId = 260883."
选项2:在应用程序启动时调用DbConfiguration.SetConfiguration(new MySqlEFConfiguration())
适当的Web.config段(实际上与选项1相同):
<connectionStrings>
<add name="MY_SqlContext"
connectionString="server=.;User Id=root;password=...;Persist Security Info=True;database=MySqlDb;Use Compression=False;Use Old Syntax=False"
providerName="MySql.Data.MySqlClient" />
<add name="Ms_SqlContext"
connectionString="metadata=res://*/Ms_SqlContext.csdl|res://*/Ms_SqlContext.ssdl|res://*/Ms_SqlContext.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=MsSqlDb;User ID=appuser;Password=...""
providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
Run Code Online (Sandbox Code Playgroud)
代码,添加到Global.asax.cs:private void Application_Start(object sender,EventArgs e){DbConfiguration.SetConfiguration(new MySqlEFConfiguration()); ...
在应用程序启动并且Web请求开始处理尝试创建Ms_SqlContext实例后,我得到异常:
设置了"MySqlEFConfiguration"的实例,但未在与"Ms_SqlContext"上下文相同的程序集中发现此类型.将DbConfiguration类型放在与DbContext类型相同的程序集中,在DbContext类型上使用DbConfigurationTypeAttribute指定DbConfiguration类型,或在配置文件中设置DbConfiguration类型.有关详细信息,请参阅...?LinkId = 260883.
选项3:在配置文件中设置DbConfiguration类型
适当的Web.config段
<connectionStrings>
<add name="MY_SqlContext"
connectionString="server=.;User Id=root;password=...;Persist Security Info=True;database=MySqlDb;Use Compression=False;Use Old Syntax=False"
providerName="MySql.Data.MySqlClient" />
<add name="Ms_SqlContext"
connectionString="metadata=res://*/Ms_SqlContext.csdl|res://*/Ms_SqlContext.ssdl|res://*/Ms_SqlContext.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=MsSqlDb;User ID=appuser;Password=...""
providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
Run Code Online (Sandbox Code Playgroud)
在应用程序启动并且Web请求开始处理之后:...创建了Ms_SqlContext实例,但在第一次查询执行期间,我得到了异常:
EntityException:{"底层提供程序在Open上失败."}
InnerException:{"无法连接到任何指定的MySQL主机."}
所以,Ms_SqlContext得到的MySql配置显然是错误的.
所以,最终的解决方案是:
使用二十一点和妓女创建自己的DbConfiguration后继者:
public class MultipleDbConfiguration : DbConfiguration
{
#region Constructors
public MultipleDbConfiguration()
{
SetProviderServices(MySqlProviderInvariantName.ProviderName, new MySqlProviderServices());
}
#endregion Constructors
#region Public methods
public static DbConnection GetMySqlConnection(string connectionString)
{
var connectionFactory = new MySqlConnectionFactory();
return connectionFactory.CreateConnection(connectionString);
}
#endregion Public methods
}
Run Code Online (Sandbox Code Playgroud)使用MultipleDbConfiguration标记Ms_SqlContext(并且对这种DbContext不做任何其他操作)
[DbConfigurationType(typeof(MultipleDbConfiguration))]
partial class Ms_SqlContext
{
}
Run Code Online (Sandbox Code Playgroud)使用MultipleDbConfiguration标记Ms_SqlContext,并使用调用MultipleDbConfiguration.GetMySqlConnection(nameOrConnectionString)调用MY_SqlContext(string nameOrConnectionString)
[DbConfigurationType(typeof(MultipleDbConfiguration))]
partial class MY_SqlContext : DbContext
{
public MY_SqlContext(string nameOrConnectionString) : base(MultipleDbConfiguration.GetMySqlConnection(nameOrConnectionString), true)
{}
}
Run Code Online (Sandbox Code Playgroud)这就对了!!!
您是正确的,每个 AppDomain 只有一个 DbConfiguration,而不是每个上下文一个。有关如何指定它的更多信息,请参见此处 - http://msdn.microsoft.com/en-us/data/jj680699#Moving。如果您有多个配置并希望确保加载正确的配置,那么您可能需要静态 DbConfiguration.SetConfiguration 方法的配置文件选项。
看起来 MySQL 正在替换依赖解析器中的一堆服务,但它们注册的实现仅适用于 MySQL。
基于代码的配置实际上是为最终开发人员设置其配置而设计的,而不是为各个提供商提供预制的配置(因为每个 AppDomain 只有一个)。
我的建议是不要使用他们的服务,创建您自己的服务并且仅注册您需要/想要的服务。例如,注册他们的执行策略是一件好事 - 并且注册是特定于提供商的:
SetExecutionStrategy(MySqlProviderInvariantName.ProviderName, () => new MySqlExecutionStrategy());
当您准确计算出需要注册哪些内容才能使其提供商正常工作时,可能会出现一些尝试和错误。
| 归档时间: |
|
| 查看次数: |
14124 次 |
| 最近记录: |