C# .Net Web Api:为什么要在Web Api控制器项目上安装实体框架?

C# .Net Web Api:为什么要在Web Api控制器项目上安装实体框架?,c#,asp.net-web-api,entity-framework-6,data-access-layer,C#,Asp.net Web Api,Entity Framework 6,Data Access Layer,我有一个多层.NETWebAPI项目,其中(除了WebAPI层本身)我有一个DAL,它将执行所有数据库操作(我正在与Oracle合作) 为此,我使用NuGet配置了数据访问层,并添加了以下三个包: 1) EntityFramework 2) Oracle.ManagedDataAccess 3) Oracle.ManagedDataAccess.EntityFramework 并定义了一个实体类,如下所示: using System.Data.Entity; public class WFR

我有一个多层.NETWebAPI项目,其中(除了WebAPI层本身)我有一个DAL,它将执行所有数据库操作(我正在与Oracle合作)

为此,我使用NuGet配置了数据访问层,并添加了以下三个包:

1) EntityFramework
2) Oracle.ManagedDataAccess
3) Oracle.ManagedDataAccess.EntityFramework
并定义了一个实体类,如下所示:

using System.Data.Entity;

public class WFRHEntities : DbContext
{
    public WFRHEntities() : base("WFRHEntities") {

        bool instanceExists = System.Data.Entity.SqlServer.SqlProviderServices.Instance != null;
    }

    public DbSet<Employee> Employees { get; set; }
    public DbSet<Vacancy> Vacancies { get; set; }

    public virtual void Commit()
    {
        base.SaveChanges();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("SYSTEM");
        modelBuilder.Configurations.Add(new EmployeeConfiguration());
    }
之后,我从Web Api项目中删除了EntityFramework(以及与Oracle相关的软件包),删除了Web Api Web.config中的所有数据设置,并在controller中调用add方法,如下所示:

namespace WFRH.Data
{
    public class VacancyRepository
    {
        public VacancyRepository() {

        }

        public void Add(Vacancy entity) {

            WFRHEntities vacancyEntity = new WFRHEntities();
            vacancyEntity.Vacancies.Add(entity);
        }
    }
}
[HttpPost]
public IEnumerable<string> Post([FromBody]Vacancy vacancy)
{
    if (vacancy == null)
    {
        throw new System.ArgumentNullException(nameof(vacancy));
    }
    VacancyRepository vr = new VacancyRepository();
    vr.Add(vacancy);

    return new string[] { "Vacancy request added correctly" };
}
[HttpPost]
公共IEnumerable职位([FromBody]空缺)
{
如果(空缺==null)
{
抛出新的System.ArgumentNullException(nameof(空缺));
}
VacancyRepository vr=新VacancyRepository();
vr.增加(空缺);
返回新字符串[]{“已正确添加空缺请求”};
}
这是我的DAL app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework"type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
      requirePermission="false"/>
    <section name="oracle.manageddataaccess.client"
      type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
  </configSections>
  <system.data>
    <DbProviderFactories>
      <remove invariant="Oracle.ManagedDataAccess.Client"/>
      <add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver"
        type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
    </DbProviderFactories>
  </system.data>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <publisherPolicy apply="no"/>
        <assemblyIdentity name="Oracle.ManagedDataAccess" publicKeyToken="89b483f429c47342" culture="neutral"/>
        <bindingRedirect oldVersion="4.122.0.0 - 4.65535.65535.65535" newVersion="4.122.18.3"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <oracle.manageddataaccess.client>
    <version number="*">
      <dataSources>
        <dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) "/>
      </dataSources>
    </version>
  </oracle.manageddataaccess.client>
  <connectionStrings>
    <add name="OracleDbContext" providerName="Oracle.ManagedDataAccess.Client"
      connectionString="User Id=oracle_user;Password=oracle_user_password;Data Source=oracle"/>
  </connectionStrings>
  <entityFramework>
    <providers>
      <provider invariantName="Oracle.ManagedDataAccess.Client"        type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342"/>
    </providers>
  </entityFramework>
</configuration>

我现在在尝试执行添加操作时收到的错误是:

using System.Data.Entity;

public class WFRHEntities : DbContext
{
    public WFRHEntities() : base("WFRHEntities") {

        bool instanceExists = System.Data.Entity.SqlServer.SqlProviderServices.Instance != null;
    }

    public DbSet<Employee> Employees { get; set; }
    public DbSet<Vacancy> Vacancies { get; set; }

    public virtual void Commit()
    {
        base.SaveChanges();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("SYSTEM");
        modelBuilder.Configurations.Add(new EmployeeConfiguration());
    }
System.Data.SqlClient.SqlException:在主数据库中创建数据库的权限被拒绝,所以现在我的问题是:

1) 为什么在my DAL app.config中,所有引用都指向Oracle而不是一个SQl Server引用时,它会引发SQl异常?
2) 当我试图向现有表中添加记录时,为什么会出现“创建数据库”错误?

您需要安装编译器在编译期间需要引用的所有内容

您的Api代码显然知道
wfRhenties
,它是DAL项目中的一个公共类。那个班有哪些成员?为了回答这个问题,我们不仅要看那个类,还要看任何基类。就像那样,BAM,我们需要了解实体框架的
DbContext

任何公开DAL中的实体框架类型1的行为都将是Api代码需要该引用的原因—可以是基类,也可以是用作任何其他成员的参数或返回类型的任何此类类型;或属性

隐藏这一点的一种常见方法是在真实上下文前面放置某种类型的façade类型,并且只在DAL中公开该类型(以及您的普通实体)


但事实是,除此之外,这还不够,因为我还需要将其添加到web.config:

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="Oracle.ManagedDataAccess.Client" 
                type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </providers>
  </entityFramework>
是的,“库”没有运行时配置文件,只有应用程序有。非Asp.Net应用程序有其
.exe.config
文件,Asp.Net应用程序有
web.config
(较新版本的Asp.Net扩展了可能的配置源)。任何运行时配置设置都需要进入该文件2。不幸的是,一些VisualStudio工具会将
app.config
文件添加到库中,使这些库看起来像是有单独的配置。我将其视为工具中的一个bug,其他人可能会慷慨地将其描述为为为您提供了一个需要放置在应用程序配置文件中的配置设置示例


1从广义上讲,“外部代码看到了这一点”。当然,这不仅是
公共的
,而且是
受保护的


2实际上可以有多个
web.config
文件处于多个级别,但通常您希望核心配置位于应用程序的基本目录中。此外,您还可以引用其他配置文件来包含部分配置,但这样做的目的是能够说明“此文件中包含整个配置部分”,而不是“查看此其他配置文件并将其内容与当前文件“合并”

您需要安装编译器在编译期间需要引用的所有内容

您的Api代码显然知道
wfRhenties
,它是DAL项目中的一个公共类。那个班有哪些成员?为了回答这个问题,我们不仅要看那个类,还要看任何基类。就像那样,BAM,我们需要了解实体框架的
DbContext

任何公开DAL中的实体框架类型1的行为都将是Api代码需要该引用的原因—可以是基类,也可以是用作任何其他成员的参数或返回类型的任何此类类型;或属性

隐藏这一点的一种常见方法是在真实上下文前面放置某种类型的façade类型,并且只在DAL中公开该类型(以及您的普通实体)


但事实是,除此之外,这还不够,因为我还需要将其添加到web.config:

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="Oracle.ManagedDataAccess.Client" 
                type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </providers>
  </entityFramework>
是的,“库”没有运行时配置文件,只有应用程序有。非Asp.Net应用程序有其
.exe.config
文件,Asp.Net应用程序有
web.config
(较新版本的Asp.Net扩展了可能的配置源)。任何运行时配置设置都需要进入该文件2。不幸的是,一些VisualStudio工具会将
app.config
文件添加到库中,使这些库看起来像是有单独的配置。我将其视为工具中的一个bug,其他人可能会慷慨地将其描述为为为您提供了一个需要放置在应用程序配置文件中的配置设置示例


1从广义上讲,“外部代码看到了这一点”。当然,这不仅是
公共的
,而且是
受保护的

2实际上可以有多个
web.config
文件处于多个级别,但通常您希望核心配置位于应用程序的基本目录中。此外,您可以引用其他配置文件来包含部分配置,但这是为了能够