.Net Web Api:为什么我应该在我的 Web Api 控制器项目上安装 Entity Framework?

.Net Web Api: Why should I install Entity Framework on my Web Api controllers project?

我有一个多层 .Net Web Api 项目,其中(除了 Web Api 层本身)我有一个 DAL,它将执行所有数据库操作(我正在使用甲骨文)。

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

1) EntityFramework
2) Oracle.ManagedDataAccess
3) Oracle.ManagedDataAccess.EntityFramework

并定义了一个实体 class 如下:

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 空位控制器中我有一个 post 方法:

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

    return new string[] { "Vacancy request added correctly" };
}

并且此方法收到来自 Angular 应用程序表单的 post 请求以创建新的职位空缺请求,但无法使其工作,因为它抱怨必须安装 Entity Framework。

关键是,从直观的角度(理论上)你没有任何理由在UI(或Web Api)项目中安装任何数据元素,即你应该拥有 DAL 的原因。

假设我不介意在 Web Api 项目中安装 Entity Framework(我使用的是 v6.0),但事实是这还不够,因为我还需要将其添加到 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>

为此我还必须通过 NuGet 添加上面提到的两个 Oracle 包,这样 Entity Framework 知道它可以与 Oracle 而不是 SQL 服务器一起工作,这样你就可以开始拥有你的 UI(或 Web Api)充满与数据相关的参考资料。

我不想(而且我认为这不是一个好主意)将所有这些东西放在任何地方,但在 DAL 和 FYI 中,我不像我那样使用存储库和工作单元模式我不了解他们,所以我尽量让事情变得简单。

接下来我正在读这个 post:

Why do I have to reference EF in my UI project?

但无法找到解决我的问题的方法(或可靠的解决方案)。

关于如何解决这个问题有什么想法吗?

从数据层完全抽象出您的 UI 真的那么难吗?

谢谢。

编辑:重写了少量代码。

我重写了一些代码,现在我在 DAL 中创建了一个 VacancyRepository class,如下所示:

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

        }

        public void Add(Vacancy entity) {

            WFRHEntities vacancyEntity = new WFRHEntities();
            vacancyEntity.Vacancies.Add(entity);
        }
    }
}

之后,我从 Web Api 项目中删除了 EntityFramework(和 Oracle 相关的包),并删除了 Web Api web.config 中的所有数据设置,并在中调用了添加方法像这样的控制器:

[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" };
}

这是我的 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>

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

System.Data.SqlClient.SqlException:在 master 数据库中创建数据库时权限被拒绝所以现在我的问题是:

1) 为什么在我的 DAL 中抛出 SQl 异常 app.config 是否清楚所有引用都是对 Oracle 而不是一个 Sql 服务器引用? 2) 为什么在我尝试向现有 table 添加记录时出现 "Create Database" 错误?

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

您的 Api 代码显然知道 WFRHEntities,这是来自您的 DAL 项目的 public class。 class 有哪些成员?为了回答这个问题,我们不仅需要查看 class,还需要查看任何基数 class。而且,就像那样,BAM,我们需要了解 Entity Framework 的 DbContext

任何 公开 一个 entity framework 类型 publicly1 从你的 DAL 将是一个原因需要该引用的 Api 代码 - 可以是基础 classes,或用作参数的任何此类类型或任何其他成员的 return 类型;或属性。

隐藏它的一种常见方法是在真实上下文之前放置某种外观类型,并且只使 那个(和你的普通实体)public 来自您的 DAL。


but the fact is that on top of all this is not enough as I also need to add this to the web.config:

是的,"libraries" 没有运行时配置文件,只有应用程序有。非 Asp.Net 应用程序有它们的 <exename>.exe.config 文件,ASP.Net 应用程序有 web.config(较新的 ASP.Net 扩展了可能的配置源)。任何运行时配置设置都需要进入 that 文件2。不幸的是,某些 Visual Studio 工具会将 app.config 文件添加到库中,这使得这些库看起来像是具有单独的配置。我将其视为工具中的一个错误,其他人可能会慷慨地将其描述为为您提供需要放置在应用程序配置文件中的配置设置示例。


1广义上使用"external code sees this"。这当然不仅仅是 public,还有 protected

2实际上可以在多个级别有多个 web.config 文件,但通常您希望核心配置位于应用程序的基本目录中。此外,您可以引用其他配置文件来包含您的部分配置,但它的设计目的是能够说 "this entire configuration section is found in this file",而不是 "look at this other config file and 'merge' its contents with the current file"