简体   繁体   中英

Entity Framework 5 with Oracle table/view doesn't exist inconsistency?

Any help or advice regarding this issue is greatly appreciated.

I am currently working on a project that requires a change in our data layer from a local MS SQL instance to a hosted Oracle solution.

Previously, we were using Entity Framework (Code-First) to build our data layer. I would like to take the same approach with the new data layer. We have several applications that use this library, so trying to keep the new data layer as close to the same (objects, names, etc.) as the original would be ideal. I know that Code-First is not officially supported by Oracle (a work in progress), but have read where others have had some success. Thus, for these reasons, I am attempting to do the same.

I have created my Oracle EF data layer to match as closely as I can to the original MS SQL EF data layer. The issue that I'm currently having is that when I run a query to retrieve the first or default entity from the data layer, I get the following exception:

Oracle.DataAccess.Client.OracleException: ORA-00942: table or view does not exist

If I use the exact same DbContext instance and instead run a sql query using the DbContext.Database.SqlQuery(sqlString), it works. The reason I mention this is because I've read the "table or view does not exist" error refers to a database permissions issue. That does not appear to be the case this time, since I'm using the exact same connection string in the same connection object. The only difference appears to be in using traditional sql statements versus the DbSet entities (& configurations).

My entities are relatively simple, flat objects.

public class HourlyPrice
{
    public DateTime MarketDate { get; set; }
    public int HourEnding { get; set; }
    public string LocationId { get; set; }
    public string LocationName { get; set; }
    public decimal? Price { get; set; }
    public int IsValid { get; set; }
    public DateTime DateInserted { get; set; }
    public DateTime? DateUpdated { get; set; }
}

public HourlyPriceConfiguration(string viewName)
{
    ToTable(viewName);
    HasKey(x => new { x.MarketDate, x.HourEnding, x.LocationName });
    Property(x => x.Price).HasPrecision(13, 6);
    HasEntitySetName("SourceHourlyPrices");
}

Inside my DbContext, I add the HourlyPriceConfiguration injecting the viewName ...

modelBuilder.Configurations.Add(new HourlyPriceConfiguration(this.viewName));

... and declare my IDbSet as ...

public IDbSet<HourlyPrice> SourceHourlyPrices { get; set; }

When running the code, this works ...

var sql = "select * from " + this.viewName;
var prices = db.Database.SqlQuery<HourlyPrice>(sql);
var price = prices.FirstOrDefault();

... but this ...

var price = db.SourceHourlyPrices.FirstOrDefault();

... produces the "table or view does not exist" error.

Is this just an issue with the Code-First approach, or am I missing something here? When debugging the application, I can see the viewName being passed to the configuration class is the same that is being passed to the sql statement used in SqlQuery. I've tried removing the HasEntitySetName() and changing the IDbSet to the standard HourlyPrices, but that didn't work, either.

Thanks again, in advance.

I would like to confirm that I had the same problem with a table name. In Oracle if the name is not full UPPER CASE the table/view is not found.

Code First Automatic Migrations is limited to working with the dbo schema only. https://community.oracle.com/thread/3622163

You can put it in beginning OnModelCreating method of your Context class as a workaround .

if (this.Database.Connection.GetType().Equals(typeof(Oracle.ManagedDataAccess.Client.OracleConnection)))
{
    modelBuilder.HasDefaultSchema(new Oracle.ManagedDataAccess.Client.OracleConnectionStringBuilder(this.Database.Connection.ConnectionString).UserID);
}

The ORA-00942 exception is not a permission issue (depends on how you look at it of course); but it means that the table you are querying is not visible to your user.

You may try to explicitly set the name of your schema in your ToTable method call by using the ToTable(tableName, schemaName) implementation and see what happens.

Just wanted to add that I had the same problem after moving the DB to a different schema. I realised that it is critically to have the schema name in upper case when using ToTable(tableName, schemaName) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM