【发布时间】: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