使用实体框架时,会加载多个Sybase dll(Multiple Sybase dlls are loaded when using entity framework)

539 IT屋

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.

解决方案

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.

我正在使用SQL Anywhere 17和实体框架6.当我尝试从数据库中获取一些数据时,我得到这个例外。



  

EntityFramework.dll中出现类型为"System.InvalidCastException"的异常,但未在用户代码
中处理其他信息:[A] Sap.Data.SQLAnywhere.SAConnection
不能转换为[B] Sap.Data.SQLAnywhere.SAConnection。类型A的起始地址为
from'Sap.Data.SQLAnywhere.v4.5,Version = 17.0.0.10624,Culture = neutral,
PublicKeyToken = f222fc4333e0d400'在上下文'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"。类型B
源自'Sap.Data.SQLAnywhere.EF6,版本= 17.0.0.10624,
文化=中立,PublicKeyToken = f222fc4333e0d400'在上下文'默认'在
位置'C: \WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Sap.Data.SQLAnywhere.EF6
\v4.0_17.0.0.10624__f222fc4333e0d400\Sap.Data.SQLAnywhere.EF6.dll'。


这是我的代码,



  public class SybaseConfiguration:DbConfiguration 
{
public SybaseConfiguration()
{
SetProviderServices("Sap.Data.SQLAnywhere",SAProviderServices.Instance);
}
}

[DbConfigurationType(typeof(SybaseConfiguration))]
public partial class SomeDatabaseContext:DbContext
{...}


//调用代码
使用(var context = new SomeDatabaseContext(connectionString)
context.GetSomeRandomTable.ToList()//我在这里得到异常
< / code>


当我创建上下文对象时,只有Sap.Data.SQLAnywehre.EF6被加载,但是当我调用GetSomeRandomTable它会加载Sap。 Data.SQLAnywhere.v4.5(它不应该),



调试器说,Sap.Data.SQLAnywhere.v4.5和Sap.Data.SQLAnywhere.EF6加载。



请注意,配置文件中没有任何内容,我是代码库配置。


解决方案

确保您在 App.config 中没有配置部分,因为
据我所知,EF将无论如何,加载它。



我是这样,它的工作原理:



  PU blic class SampleDbConfiguration:DbConfiguration 
{
public SampleDbConfiguration()
{
//设置提供者
SetProvider();
}

///< summary>
///将Sql-Aynwhere设置为当前实体框架提供程序
///< / summary>
private void SetProvider()
{
//不需要...
this.SetDefaultConnectionFactory(new SampleDBConnectionFactory());

this.SetProviderServices("iAnywhere.Data.SQLAnywhere",iAnywhere.Data.SQLAnywhere.SAProviderServices.Instance);
this.SetProviderFactory("iAnywhere.Data.SQLAnywhere",iAnywhere.Data.SQLAnywhere.SAFactory.Instance);
}
}


只需将其替换为不变名称,因为我们是使用sybase 16.另外
确保您不引用其他dll,并且不通过(例如) LoadAssembly 加载它。



编辑



这不是必需的,但是如果你想要的话可​​以创建自己的DbConnection to。



 内部类SampleDBConnectionFactory:IDbConnectionFactory 
{
///< summary>
///创建SA-DB连接
///< / summary>
///< param name ="nameOrConnectionString">完整连接字符串的名称< / param>
///< returns>与sybase连接的实例db< / returns>
public System.Data.Common.DbConnection CreateConnection(string nameOrConnectionString)
{
SAConnection connection = new SAConnection(ConnectionManager.GetConnectionString(nameOrConnectionString?"Default"));

返回连接;
}
}


希望thius有帮助。


本文地址:IT屋 » 使用实体框架时,会加载多个Sybase dll