【问题标题】:.Net Web Api: Why should I install Entity Framework on my Web Api controllers project?.Net Web Api:为什么要在我的 Web Api 控制器项目上安装 Entity Framework?
【发布时间】:2019-03-13 22:16:21
【问题描述】:

我有一个多层 .Net Web Api 项目,其中(除了 Web Api 层本身)我有一个 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 Vacancy 控制器中,我有一个 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 应用程序表单接收发布请求以创建新的空缺请求,但无法使其工作,因为它抱怨必须安装实体框架。

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

假设我不介意在 Web Api 项目中安装 Entity Framework(我使用的是 v6.0),但事实是这还不够,因为我还需要将其添加到网络中.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 Server 一起使用,这样你就可以开始让你的 UI(或 Web Api)充满数据相关东西参考。

我不希望(而且我认为这不是一个好主意)在 DAL 和仅供参考之外的任何地方拥有所有这些东西我不使用存储库和工作单元模式,因为我不知道所以我尽量让事情变得简单。

我正在阅读下一篇文章:

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

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

关于如何解决这个问题的任何想法?

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

谢谢。

编辑:重写了少量代码。

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

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 中的所有数据设置,并在控制器中调用 add 方法,如下所示:

[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:在主数据库中创建数据库时权限被拒绝所以现在我的问题是:

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

【问题讨论】:

    标签: c# asp.net-web-api entity-framework-6 data-access-layer


    【解决方案1】:

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

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

    任何公开从您的 DAL 公开的实体框架类型1 的内容都是 Api 代码需要该引用的原因 - 这可能是基类或任何用作任何其他成员的参数或返回类型的此类类型;或属性。

    隐藏这一点的一种常见方法是在真实上下文之前放置某种外观类型,并且仅将 那个(以及您的普通实体)从您的 DAL 中公开。


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

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


    1用于广义的“外部代码看到这个”。当然不只是public,还有protected

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

    【讨论】:

    • 非常感谢您的帮助@Damien_The_Unbeliever。请看我的编辑。我已经重写了一些代码,现在我认为我部分解决了我的问题,但得到了一个不同的错误。
    • @DiegoPerez - 我已经尝试在答案的第二部分中涵盖这一点。您的 DAL 没有 配置文件,尽管任何 VS 工具可能会误导您(或者您明确添加了一个)。配置需要在 web.config 中。
    • 哦,是的,你做得很好很抱歉,现在 - 虽然我拒绝 - 我开始相信你肯定必须将所有数据配置和引用放在你的 UI 中,尽管你有一个 DAL 用于那:(
    • @DiegoPerez - 如果您所做的只是将提及它的内容放在配置中,以便在运行时使用,那么您本身不需要参考。您当然需要 DLL 本身存在于 bin 目录中,因为您的 DAL 依赖于它们。
    • 再次感谢@Damien_The_Unbeliever,你很友善。鉴于此,我猜在我的 DAL 中我不需要通过 Nuget(Oracle.ManagedDataAccess 和 Oracle.ManagedDataAccess.EntityFramework)安装 Oracle 包,因为它们已经安装在 Web Api 项目中并且只需要实体框架包,或者我是错了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多