简体   繁体   English

带有Oracle表/视图的Entity Framework 5是否不存在不一致?

[英]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. 我目前正在从事一个项目,该项目需要将我们的数据层从本地MS SQL实例更改为托管Oracle解决方案。

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. 我知道Code-First并没有得到Oracle的正式支持(正在进行中),但是已经阅读了其他人取得了一些成功的地方。 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. 我已经创建了Oracle EF数据层,以使其与原始MS SQL EF数据层尽可能地匹配。 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 Oracle.DataAccess.Client.OracleException:ORA-00942:表或视图不存在

If I use the exact same DbContext instance and instead run a sql query using the DbContext.Database.SqlQuery(sqlString), it works. 如果我使用完全相同的DbContext实例,而是使用DbContext.Database.SqlQuery(sqlString)运行sql查询,则它将起作用。 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). 唯一的区别似乎在于使用传统的sql语句与DbSet实体(和配置)。

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 ... 在我的DbContext中,我添加HourlyPriceConfiguration注入viewName ...

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

... and declare my IDbSet as ... ...并将我的IDbSet声明为...

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? 这仅仅是Code-First方法的问题,还是我在这里遗漏了一些东西? 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. 在调试应用程序时,我可以看到传递给配置类的viewName与传递给SqlQuery中使用的sql语句的视图名相同。 I've tried removing the HasEntitySetName() and changing the IDbSet to the standard HourlyPrices, but that didn't work, either. 我试过删除HasEntitySetName()并将IDbSet更改为标准HourlyPrices,但这也不起作用。

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. 在Oracle中,如果名称不全为大写,则找不到表/视图。

Code First Automatic Migrations is limited to working with the dbo schema only. 代码优先自动迁移仅限于仅使用dbo模式。 https://community.oracle.com/thread/3622163 https://community.oracle.com/thread/3622163

You can put it in beginning OnModelCreating method of your Context class as a workaround . 您可以将其放在Context类的开始OnModelCreating方法中,作为解决方法

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); ORA-00942异常不是权限问题(当然取决于您的看法); 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. 您可以尝试使用ToTable(tableName, schemaName)实现在ToTable方法调用中显式设置模式的名称,然后看看会发生什么。

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) . 我意识到,使用ToTable(tableName, schemaName)时,具有大写字母的架构名称至关重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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