programing

EF 6 및 Oracle을 사용하는 동안 테이블이 존재하지 않습니다.관리 데이터 액세스

subpage 2023. 10. 21. 10:28
반응형

EF 6 및 Oracle을 사용하는 동안 테이블이 존재하지 않습니다.관리 데이터 액세스

저는 EF를 사용하여 MVC 어플리케이션을 만들고 있습니다.6.0.0.0ODP.NetOracle.ManagedDataAccess버전4.121.2.0데이터 액세스를 위해 사용됩니다.

나의Controller불렀다EmployeeController, 다음 코드 스니펫이 있습니다.

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페이지 다음 예외가 표시됨:

"명령어 정의를 실행하는 동안 오류가 발생했습니다.자세한 내용은 내부 예외를 참조하십시오."

그리고 내부 예외에는 이렇게 적혀있습니다.

ORA-00942: 테이블 또는 뷰가 존재하지 않습니다

Oracle Database에는 테이블이 분명히 존재하기 때문에(Toad for Oracle을 사용하여 확인했습니다) 이 문제는 매우 당혹스럽습니다.

enter image description here

connectionString데이터베이스 자체는 제가 다른 프로젝트에 사용하는 것과 동일한 연결 문자열이고 데이터베이스에서 데이터를 어렵지 않게 조회할 수 있었기 때문입니다.

이렇게 제.Employee클래스는 에서 선언됩니다.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);
}

표가 존재하지 않는 경우 여전히 오류가 발생하는 것은 무엇입니까?여기서 무엇이 잘못될 수 있습니까?그런 경우를 디버그하는 방법을 제안해 주시겠습니까?

편집:

제가 평가할 때.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);

디버그 출력 창에 다음이 표시됩니다.

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발견되지 않았습니다, 데빌 Suichiro가 코멘트에서 제시한 것처럼, 잘못된 것 때문이었습니다.Schemaused. 기본적으로 EF 6 useddbo기본 스키마로 지정하지만 내 스키마는 그렇지 않습니다.dbo. 모델에 기본 스키마를 사용하도록 하려면 다음 값을 재정의합니다.OnModelCreating이벤트가 필요합니다.

public class EmployeeContext : DbContext {
    public DbSet<Employee> Employees { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.HasDefaultSchema("myschema");
    }
}

또한 EF에서 생성된 SQL을 확인해달라는 이반 스토예프의 제안에 감사드립니다.

우리도 같은 문제가 있었습니다.우리가 발견한 것은 edmx 파일에서 잘못된 데이터베이스 스키마에 대한 참조입니다.

<EntitySet Name="MyTable" EntityType="Self.MyTable" Schema="**wrongSchemaName**" store:Type="Tables" />

스키마 이름을 삭제하여 문제가 해결되었습니다.

<EntitySet Name="MyTable" EntityType="Self.MyTable" Schema="" store:Type="Tables" />

제 경우에는 스캐폴드를 다시 실행하여 문제를 해결했고, 다음과 같은 단계를 거쳤습니다.

1- Tools 메뉴를 클릭하고 NuGet Package Manager를 선택한 다음 Package Manager Console을 선택합니다.

2 - scaffold 명령어를 실행하고 연결 문자열을 다음 스크립트로 사용하여 DBcontext 및 Models를 작성하고 테이블을 전체 설정으로 다시 가져옵니다.

Scaffold-DbContext "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host)(PORT=1521)))(CONNECT_DATA=(SID=orcl)));User ID=scott;Password=tiger" 

-Provider Oracle.EntityFrameworkCore 

-OutputDir    Models    

-Tables table1,table2,table3 -force

언급URL : https://stackoverflow.com/questions/35403610/table-does-not-exist-while-using-ef-6-and-oracle-manageddataaccess

반응형