Table 在使用 EF 6 和 Oracle.ManagedDataAccess 时不存在
Table Does Not Exist while using EF 6 and Oracle.ManagedDataAccess
我正在使用 EF 6.0.0.0
和 ODP.Net Oracle.ManagedDataAccess
版本 4.121.2.0
创建 MVC 应用程序以进行数据访问。
在名为 EmployeeController
的 Controller
中,我有以下代码片段:
public ActionResult Details(int id) {
try {
EmployeeContext employeeContext = new EmployeeContext();
Employee employee = employeeContext.Employees.Single(x => x.Id == id); //Here the exception occurs!
return View(employee);
} catch (Exception e) {
return View(e);
}
}
当我加载 Employee/Details.cshtml
页面时,出现以下异常:
"An error occurred while executing the command definition. See the
inner exception for details."
在内部异常中,它说:
ORA-00942: table or view does not exist
这让我感到困惑,因为在我的 Oracle 数据库中,table 肯定存在(我使用 Toad for Oracle 检查过):
数据库本身的 connectionString
与我用于其他项目的连接字符串相同,我可以在其中轻松地从数据库中查询数据。
下面是我的 Employee
class 在 Models/Employee.cs
中的声明方式:
using System.ComponentModel.DataAnnotations.Schema;
.
.
.
[Table("TBLEMPLOYEE")] //the same table name
public class Employee {
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public DateTime DateOfBirth { get; set; }
public int EmployeeType { get; set; }
public double? AnnualSalary { get; set; }
public double? HourlyPay { get; set; }
public double? HoursWorked { get; set; }
public string City { get; set; }
}
而我的 Models/EmployeeContext.cs
仅由一个元素组成:
using System.Data.Entity;
.
.
.
public class EmployeeContext : DbContext {
public DbSet<Employee> Employees { get; set; }
}
并且在 Global.asax.cs
文件中,我已经为 EmployeeContext
模型初始化了数据库:
protected void Application_Start() { //executed at the very beginning
Database.SetInitializer<MvcWebApplication1.Models.EmployeeContext>(null); //null -> no initialization strategy
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
如果 Table 不存在,我仍然会收到什么错误消息?这里可能出什么问题?对如何调试这种情况有什么建议吗?
编辑:
当我评估 employeeContext.Employees
时,我得到以下值:
{SELECT
"Extent1"."Id" AS "Id",
"Extent1"."Name" AS "Name",
"Extent1"."Gender" AS "Gender",
"Extent1"."DateOfBirth" AS "DateOfBirth",
"Extent1"."EmployeeType" AS "EmployeeType",
"Extent1"."AnnualSalary" AS "AnnualSalary",
"Extent1"."HourlyPay" AS "HourlyPay",
"Extent1"."HoursWorked" AS "HoursWorked",
"Extent1"."City" AS "City"
FROM "dbo"."TBLEMPLOYEE" "Extent1"}
编辑 2:
使用:
employeeContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
我在调试输出中得到以下内容 window:
SELECT
"Extent1"."Id" AS "Id",
"Extent1"."Name" AS "Name",
"Extent1"."Gender" AS "Gender",
"Extent1"."DateOfBirth" AS "DateOfBirth",
"Extent1"."EmployeeType" AS "EmployeeType",
"Extent1"."AnnualSalary" AS "AnnualSalary",
"Extent1"."HourlyPay" AS "HourlyPay",
"Extent1"."HoursWorked" AS "HoursWorked",
"Extent1"."City" AS "City"
FROM "dbo"."TBLEMPLOYEE" "Extent1"
WHERE ("Extent1"."Id" = :p__linq__0) AND (ROWNUM <= (2) )
编辑 3:
这是我的连接字符串的样子,以备不时之需
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-MvcWebApplication1-20160212010850.mdf;Initial Catalog=aspnet-MvcWebApplication1-20160212010850;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="EmployeeContext" connectionString="Data source=thisisfakedatasource;user id=thisisfakename;password=thisisfakepassword;persist security info=True"
providerName="Oracle.ManagedDataAccess.Client"/>
</connectionStrings>
而entityFramework的设置如下:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</providers>
</entityFramework>
任何问题可能出在哪里的线索?
附加信息:
异常堆栈跟踪:
e.StackTrace
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable`1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Single[TSource](IQueryable`1 source, Expression`1 predicate)
at MvcWebApplication1.Controllers.EmployeeController.Details(Int32 id) in c:\myapp\Controllers\EmployeeController.cs:line 25
内部异常堆栈跟踪:
(e.InnerException).StackTrace
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, Boolean isDescribeOnly, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
Data Table
未找到的问题,如评论中DevilSuichiro 所指出的,是由于使用了错误的Schema
。默认情况下,EF 6 使用 dbo
作为默认架构,而我的架构不是 dbo
。要使模型具有默认架构,需要覆盖 OnModelCreating
事件:
public class EmployeeContext : DbContext {
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.HasDefaultSchema("myschema");
}
}
另外,感谢 Ivan Stoev 建议检查 EF 生成的 SQL。
我们遇到了同样的问题。
我们发现在 edmx 文件中引用了错误的数据库模式:
<EntitySet Name="MyTable" EntityType="Self.MyTable" Schema="**wrongSchemaName**" store:Type="Tables" />
通过删除架构名称,我们的问题得到解决。
<EntitySet Name="MyTable" EntityType="Self.MyTable" Schema="" store:Type="Tables" />
我正在使用 EF 6.0.0.0
和 ODP.Net Oracle.ManagedDataAccess
版本 4.121.2.0
创建 MVC 应用程序以进行数据访问。
在名为 EmployeeController
的 Controller
中,我有以下代码片段:
public ActionResult Details(int id) {
try {
EmployeeContext employeeContext = new EmployeeContext();
Employee employee = employeeContext.Employees.Single(x => x.Id == id); //Here the exception occurs!
return View(employee);
} catch (Exception e) {
return View(e);
}
}
当我加载 Employee/Details.cshtml
页面时,出现以下异常:
"An error occurred while executing the command definition. See the inner exception for details."
在内部异常中,它说:
ORA-00942: table or view does not exist
这让我感到困惑,因为在我的 Oracle 数据库中,table 肯定存在(我使用 Toad for Oracle 检查过):
数据库本身的 connectionString
与我用于其他项目的连接字符串相同,我可以在其中轻松地从数据库中查询数据。
下面是我的 Employee
class 在 Models/Employee.cs
中的声明方式:
using System.ComponentModel.DataAnnotations.Schema;
.
.
.
[Table("TBLEMPLOYEE")] //the same table name
public class Employee {
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public DateTime DateOfBirth { get; set; }
public int EmployeeType { get; set; }
public double? AnnualSalary { get; set; }
public double? HourlyPay { get; set; }
public double? HoursWorked { get; set; }
public string City { get; set; }
}
而我的 Models/EmployeeContext.cs
仅由一个元素组成:
using System.Data.Entity;
.
.
.
public class EmployeeContext : DbContext {
public DbSet<Employee> Employees { get; set; }
}
并且在 Global.asax.cs
文件中,我已经为 EmployeeContext
模型初始化了数据库:
protected void Application_Start() { //executed at the very beginning
Database.SetInitializer<MvcWebApplication1.Models.EmployeeContext>(null); //null -> no initialization strategy
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
如果 Table 不存在,我仍然会收到什么错误消息?这里可能出什么问题?对如何调试这种情况有什么建议吗?
编辑:
当我评估 employeeContext.Employees
时,我得到以下值:
{SELECT
"Extent1"."Id" AS "Id",
"Extent1"."Name" AS "Name",
"Extent1"."Gender" AS "Gender",
"Extent1"."DateOfBirth" AS "DateOfBirth",
"Extent1"."EmployeeType" AS "EmployeeType",
"Extent1"."AnnualSalary" AS "AnnualSalary",
"Extent1"."HourlyPay" AS "HourlyPay",
"Extent1"."HoursWorked" AS "HoursWorked",
"Extent1"."City" AS "City"
FROM "dbo"."TBLEMPLOYEE" "Extent1"}
编辑 2:
使用:
employeeContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
我在调试输出中得到以下内容 window:
SELECT
"Extent1"."Id" AS "Id",
"Extent1"."Name" AS "Name",
"Extent1"."Gender" AS "Gender",
"Extent1"."DateOfBirth" AS "DateOfBirth",
"Extent1"."EmployeeType" AS "EmployeeType",
"Extent1"."AnnualSalary" AS "AnnualSalary",
"Extent1"."HourlyPay" AS "HourlyPay",
"Extent1"."HoursWorked" AS "HoursWorked",
"Extent1"."City" AS "City"
FROM "dbo"."TBLEMPLOYEE" "Extent1"
WHERE ("Extent1"."Id" = :p__linq__0) AND (ROWNUM <= (2) )
编辑 3:
这是我的连接字符串的样子,以备不时之需
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-MvcWebApplication1-20160212010850.mdf;Initial Catalog=aspnet-MvcWebApplication1-20160212010850;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="EmployeeContext" connectionString="Data source=thisisfakedatasource;user id=thisisfakename;password=thisisfakepassword;persist security info=True"
providerName="Oracle.ManagedDataAccess.Client"/>
</connectionStrings>
而entityFramework的设置如下:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</providers>
</entityFramework>
任何问题可能出在哪里的线索?
附加信息:
异常堆栈跟踪:
e.StackTrace
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable`1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Single[TSource](IQueryable`1 source, Expression`1 predicate)
at MvcWebApplication1.Controllers.EmployeeController.Details(Int32 id) in c:\myapp\Controllers\EmployeeController.cs:line 25
内部异常堆栈跟踪:
(e.InnerException).StackTrace
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, Boolean isDescribeOnly, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
Data Table
未找到的问题,如评论中DevilSuichiro 所指出的,是由于使用了错误的Schema
。默认情况下,EF 6 使用 dbo
作为默认架构,而我的架构不是 dbo
。要使模型具有默认架构,需要覆盖 OnModelCreating
事件:
public class EmployeeContext : DbContext {
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.HasDefaultSchema("myschema");
}
}
另外,感谢 Ivan Stoev 建议检查 EF 生成的 SQL。
我们遇到了同样的问题。 我们发现在 edmx 文件中引用了错误的数据库模式:
<EntitySet Name="MyTable" EntityType="Self.MyTable" Schema="**wrongSchemaName**" store:Type="Tables" />
通过删除架构名称,我们的问题得到解决。
<EntitySet Name="MyTable" EntityType="Self.MyTable" Schema="" store:Type="Tables" />