zoukankan      html  css  js  c++  java
  • 【异常处理】无法将类型为“Glimpse.Ado.AlternateType.GlimpseDbConnection”的对象强制转换为类型“System.Data.SqlClient.SqlConnection”。

    解决了一个棘手的EF框架引入问题,所以做下记录。

    最近在集成EF到现有系统中,由于现有系统比较旧,调用ToList的时候就会报这个错误

    错误代码

    var file = _ctx.FileInfo.FirstOrDefault(t => t.ID == uid);

    报错信息

    Unable to determine the provider name for provider factory of type 'System.Data.SqlClient.SqlClientFactory'. Make sure that the ADO.NET provider is installed or registered in the application config.

    无法将类型为“Glimpse.Ado.AlternateType.GlimpseDbConnection”的对象强制转换为类型“System.Data.SqlClient.SqlConnection”。

    堆栈1

    System.NotSupportedException: Unable to determine the provider name for provider factory of type 'System.Data.SqlClient.SqlClientFactory'. Make sure that the ADO.NET provider is installed or registered in the application config. 
    在 System.Data.Entity.Utilities.DbProviderFactoryExtensions.GetProviderInvariantName(DbProviderFactory factory)
    在 System.Data.Entity.Infrastructure.DependencyResolution.DefaultInvariantNameResolver.GetService(Type type, Object key)
    在 System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
    在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
    在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
    在 System.Data.Entity.Infrastructure.DependencyResolution.RootDependencyResolver.GetService(Type type, Object key)
    在 System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
    在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
    在 System.Data.Entity.Infrastructure.DependencyResolution.CompositeResolver`2.GetService(Type type, Object key)
    在 System.Data.Entity.Infrastructure.DependencyResolution.DbDependencyResolverExtensions.GetService[T](IDbDependencyResolver resolver, Object key)
    在 System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInvariantName(DbConnection connection)
    在 System.Data.Entity.Internal.InternalConnection.get_ProviderName()
    在 System.Data.Entity.Internal.DefaultModelCacheKeyFactory.Create(DbContext context)
    在 System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
    在 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
    在 System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
    在 System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
    在 System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
    在 System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
    在 UFSoft.UBF.MVC.MainController.TestEF(String uid)

    堆栈2

    System.InvalidCastException: 无法将类型为“Glimpse.Ado.AlternateType.GlimpseDbConnection”的对象强制转换为类型“System.Data.SqlClient.SqlConnection”。 
    在 System.Data.SqlClient.SqlCommand.set_DbConnection(DbConnection value)
    在 System.Data.Entity.Core.Common.Utils.CommandHelper.SetStoreProviderCommandState(EntityCommand entityCommand, EntityTransaction entityTransaction, DbCommand storeProviderCommand)
    在 System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.PrepareEntityCommandBeforeExecution(EntityCommand entityCommand)
    在 System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
    在 System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
    在 System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
    在 System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.b__9()
    在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
    在 System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
    在 System.Data.Entity.Core.Objects.ObjectQuery`1..GetEnumerator>b__0()
    在 System.Lazy`1.CreateValue()
    在 System.Lazy`1.LazyInitValue()
    在 System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
    在 System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
    在 System.Data.Entity.Migrations.History.HistoryRepository.QueryExists(String contextKey)
    在 System.Data.Entity.Migrations.History.HistoryRepository.Exists(String contextKey)
    在 System.Data.Entity.Migrations.History.HistoryRepository.GetLastModel(String& migrationId, String contextKey)
    在 System.Data.Entity.Migrations.History.HistoryRepository.GetLastModel()
    在 System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata)
    在 System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context)
    在 System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
    在 System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
    在 System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
    在 System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
    在 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
    在 System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
    在 System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
    在 System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
    在 System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
    在 UFSoft.UBF.MVC.MainController.TestEF(String uid)
    位置 G:yonyouU9CEUBFUBFADFUIUI_MVCControllerMainController.cs:行号 3402

    首先看了下第一个报错

    应该是配置问题导致的,所以新建了一个EF项目,看到默认的配置文件,进行对比。

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      https://go.microsoft.com/fwlink/?LinkId=169433
      -->
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>
      <system.codedom>
        <compilers>
          <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
          <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=&quot;Web&quot; /optionInfer+" />
        </compilers>
      </system.codedom>
      <entityFramework>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="v13.0" />
          </parameters>
        </defaultConnectionFactory>
      </entityFramework>
      <connectionStrings>
        <add name="Model1" connectionString="data source=lijianhua;initial catalog=U9CE20210418Doc;persist security info=True;user id=sa;password=******;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
      </connectionStrings>
    </configuration>

    看到了连接字符串后面带一个 providerName 参数,但是我的项目里连接字符串是动态配置的,没法写到配置文件里,只能通过代码实现传入 providerName 

    所以创建 DbConnection 的时候是直接 new 出来的,所以EF并不能识别这个类型。

    用下面的工厂模式方式创建即可

            public static DbConnection GetConn(string connstr)
            {
                var connection = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
                connection.ConnectionString = connstr;
                //配置了 U9_Glimpse_Allowed 才会返回此类型
                //if (UFIDA.U9.UI.PDHelper.FormAuthorityHelper.IsUserInRole("Glimpse", long.Parse(CSContext.Current.OrgId), long.Parse(CSContext.Current.UserID)))
                if (connection is GlimpseDbConnection)
                {
                    return ((GlimpseDbConnection)connection).InnerConnection as SqlConnection;
                }
                return connection;
            }

    但是创建完之后,发现了第二个报错。

    创建出来的类型并不是我需要的 DbConnection 类型,是得到的 GlimpseDbConnection 类型,这是由于目前的老框架在这块进行了区分,这个GlimpseDbConnection 是为了分析性能而特别创建的 Connection 。但是EF并不能接收这个类型。

    所以采用后面的转换方式进行转换即可正常使用。

    参考文档1

    http://aiuxian.com/article/p-tewsmagq-btb.html

    参考文档2

    百度快照

    至此已经可以正常在项目里使用EF框架,进行愉快的增删改查了。

    EF集成工作圆满结束!!!

    每天进步一丢丢
    防盗签名:本文来自【博客园】-【多安分】

    恭喜兄dei,看到这个隐藏标签~~~如果觉得博客内容有所帮助,请扫二维码打赏,感谢老铁

    支付宝

    微信

  • 相关阅读:
    Visual Assist X 安装失败解决办法
    ACM-水池数目问题
    代码生成器 CodeBuilder 2.7 新版发布
    Fireasy 官网改版
    跟我学: 使用 fireasy 搭建 asp.net core 项目系列之三 —— 配置
    跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— 准备
    跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇
    nopCommerce 学习之路(一)Nop之强制拆迁
    平庸技术流,用 WebApi +AngularJS 实现网络爬虫
    nopCommerce 学习之路(二)从EF到NPoco
  • 原文地址:https://www.cnblogs.com/jhli/p/15355937.html
Copyright © 2011-2022 走看看