问题
I am using SQL Anywhere 17 and entity framework 6. When I try to get some data from the database I get this exception.
An exception of type 'System.InvalidCastException' occurred in
EntityFramework.dll but was not handled in user code
Additional information: [A]Sap.Data.SQLAnywhere.SAConnection
cannot be cast to [B]Sap.Data.SQLAnywhere.SAConnection. Type A originates
from 'Sap.Data.SQLAnywhere.v4.5, Version=17.0.0.10624, Culture=neutral,
PublicKeyToken=f222fc4333e0d400' in the context 'Default' at
location 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Sap.Data.SQLAnywhere.v4.5
\v4.0_17.0.0.10624__f222fc4333e0d400\Sap.Data.SQLAnywhere.v4.5.dll'. Type B
originates from 'Sap.Data.SQLAnywhere.EF6, Version=17.0.0.10624,
Culture=neutral, PublicKeyToken=f222fc4333e0d400' in the context 'Default' at
location 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Sap.Data.SQLAnywhere.EF6
\v4.0_17.0.0.10624__f222fc4333e0d400\Sap.Data.SQLAnywhere.EF6.dll'.
Here is my code,
public class SybaseConfiguration : DbConfiguration
{
public SybaseConfiguration()
{
SetProviderServices("Sap.Data.SQLAnywhere", SAProviderServices.Instance);
}
}
[DbConfigurationType(typeof(SybaseConfiguration))]
public partial class SomeDatabaseContext : DbContext
{ ... }
// Calling code,
using (var context = new SomeDatabaseContext(connectionString)
context.GetSomeRandomTable.ToList() // I get exception here.
When I make context object, only Sap.Data.SQLAnywehre.EF6 is loaded. But when I call GetSomeRandomTable it loads Sap.Data.SQLAnywhere.v4.5 (which it should not),
Debugger says that both Sap.Data.SQLAnywhere.v4.5 and Sap.Data.SQLAnywhere.EF6 are loaded.
Note that there is nothing in the config file. I am code base configuration.
回答1:
Make sure you have no configuration section for this in the App.config
, because
as far as i know, EF will load it in anyway.
I'm this and it works perfectly:
public class SampleDbConfiguration : DbConfiguration
{
public SampleDbConfiguration()
{
// Set provider
SetProvider();
}
/// <summary>
/// Set Sql-Aynwhere as the current entity framework provider
/// </summary>
private void SetProvider()
{
// not required...
this.SetDefaultConnectionFactory(new SampleDBConnectionFactory());
this.SetProviderServices("iAnywhere.Data.SQLAnywhere", iAnywhere.Data.SQLAnywhere.SAProviderServices.Instance);
this.SetProviderFactory("iAnywhere.Data.SQLAnywhere", iAnywhere.Data.SQLAnywhere.SAFactory.Instance);
}
}
Just replace it with your invariant name, cause we are using sybase 16. Also
make sure, that you don't reference the other dll and do not load it via (for example) LoadAssembly
.
EDIT
This is not needed, but allows you to create your own DbConnection if you want to.
internal class SampleDBConnectionFactory : IDbConnectionFactory
{
/// <summary>
/// Create SA-DB Connection
/// </summary>
/// <param name="nameOrConnectionString">Name of complete connection string</param>
/// <returns>Instance of an SQL-Connection to a sybase db</returns>
public System.Data.Common.DbConnection CreateConnection(string nameOrConnectionString)
{
SAConnection connection = new SAConnection(ConnectionManager.GetConnectionString(nameOrConnectionString ?? "Default"));
return connection;
}
}
Hope thius helps.
来源:https://stackoverflow.com/questions/36083763/multiple-sybase-dlls-are-loaded-when-using-entity-framework