无法确定类型为'System.Data.SqlClient.SqlClientFactory的提供程序工厂的提供程序名称

时间:2019-04-17 16:11:42

标签: c# entity-framework .net-core

我有一个带有控制器的.Net Core WebApi项目,该控制器对服务,类库进行调用以获取数据。该服务使用实体框架,而不是EFCore。错误失败,在这里:

public IEnumerable<TEntity> GetAll()
{
    return _dbContext.Set<TEntity>().AsNoTracking().ToList();
}

这是错误:

  

System.NotSupportedException:无法确定类型为System.Data.SqlClient.SqlClientFactory的提供程序工厂的提供程序名称。确保已在应用程序配置中安装或注册了ADO.NET提供程序。'

我知道可以做到这一点,并且根据本文,这是将.NetCore与EF结合使用的首选方式:https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6?view=aspnetcore-2.2

  

“在ASP.NET Core应用程序中使用Entity Framework 6的推荐方法是将EF6上下文和模型类放在针对整个框架的类库项目中。从ASP中添加对类库的引用。 NET Core项目。请参阅带有EF6和ASP.NET Core项目的示例Visual Studio解决方案。”

这是Microsoft提供的示例:https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/data/entity-framework-6/sample

这是我的appsettings.json文件:

    {
        "ConnectionStrings": {
            "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=Savi-   Development;Trusted_Connection=True;"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Warning"
            }
        },
        "AllowedHosts": "*"
    } 

这是我的startup.cs:

    public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddScoped<ApplicationDbContext>(_ => new ApplicationDbContext(Configuration.GetConnectionString("DefaultConnection")));
            services.AddScoped<IRegionService, RegionService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

这是我认为正确的我的project.cs文件。它引用了完整的entityframework。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="EntityFramework" Version="6.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
    <PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\Savi.Services\Savi.Services.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Reference Include="EntityFramework.SqlServer">
      <HintPath>..\..\Savi.Services\bin\Debug\EntityFramework.SqlServer.dll</HintPath>
    </Reference>
  </ItemGroup>

</Project>

我没有project.fragment.json文件。

2 个答案:

答案 0 :(得分:1)

尝试像在链接的示例中那样进行操作,并手动构建配置,而不是通过构造函数注入配置。

例如,在Startup类中

public IConfiguration Configuration { get; }

public Startup(IHostingEnvironment env) {
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}

public void ConfigureServices(IServiceCollection services) {
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddScoped<ApplicationDbContext>(_ => 
        new ApplicationDbContext(Configuration.GetConnectionString("DefaultConnection")));
    services.AddScoped<IRegionService, RegionService>();

    //...
}

//...rest omitted for brevity

接下来,我建议您通过搜索您在.Net Core上下文中声明的异常找到的答案,复习这些建议。

System.NotSupportedException: Unable to determine the provider name for provider factory of type 'System.Data.SqlClient.SqlClientFactory'

摘要

  

您无法将Core .csproj 文件从<TargetFramework>netcoreapp2.2</TargetFramework>更改为<TargetFramework>net471</TargetFramework>

使Entity Framework类(在.NET Framework类库中)由Entity Framework的DotNet Core版本而不是Entity Framework的.NET Framework版本访问。

您的链接文章也指出

  

Reference full framework and EF6 in the ASP.NET Core project

     

您的ASP.NET Core项目需要引用.NET框架和EF6。   例如,您的ASP.NET Core项目的.csproj文件将看起来   与以下示例类似(仅文件的相关部分为   显示)。

<PropertyGroup>
  <TargetFramework>net452</TargetFramework>
  <PreserveCompilationContext>true</PreserveCompilationContext>
  <AssemblyName>MVCCore</AssemblyName>
  <OutputType>Exe</OutputType>
  <PackageId>MVCCore</PackageId>
</PropertyGroup>
     

创建新项目时,使用 ASP.NET Core Web应用程序   (.NET Framework)模板。

答案 1 :(得分:1)

我通过以下操作对其进行了修复:

  1. 创建一个新的“ ASP.NET Core Web应用程序”,然后选择“ Net 框架”而不是“核心”。选择“ Api”。
  2. 使用与以前相同的代码创建一个新的“ RegionsController”。
  3. 将所有引用添加到我现有的项目中。
  4. 在我的新“ Api”项目中添加了对“ EntityFramework”的引用。
  5. 将解决方案中的所有当前项目更新为“框架4.7.2”。这有 与错误无关,但我想指出这一点。
  6. 使用nuget将“ Newtonsoft”添加到“ Api”。
  7. 使用与以前相同的代码更新了新的“ Startup.cs”。
  8. 在appsettings.json中添加了一个连接字符串。

@Nikosi指出,此引用https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6?view=aspnetcore-2.1#reference-full-framework-and-ef6-in-the-aspnet-core-project特别表示“创建新项目时,请使用ASP.NET Core Web应用程序(.NET Framework)模板。”这就是答案。