Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 如何配置DbContext以使用Oracle ODP.Net和EF CodeFirst?_Asp.net Mvc 3_Oracle_Ef Code First_Odp.net_Dbcontext - Fatal编程技术网

Asp.net mvc 3 如何配置DbContext以使用Oracle ODP.Net和EF CodeFirst?

Asp.net mvc 3 如何配置DbContext以使用Oracle ODP.Net和EF CodeFirst?,asp.net-mvc-3,oracle,ef-code-first,odp.net,dbcontext,Asp.net Mvc 3,Oracle,Ef Code First,Odp.net,Dbcontext,我正试图在Oracle的ODP.net下使用EF CodeFirst。这是我的DbContext类: public class MyCEContext : DbContext { public DbSet<Person> Persons { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entit

我正试图在Oracle的ODP.net下使用EF CodeFirst。这是我的DbContext类:

    public class MyCEContext : DbContext {

    public DbSet<Person> Persons { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Person>().ToTable("PERSONS","myce");

    }

    public MyCEContext() : 
        base(new OracleConnection(
            "Data Source=cebd; User ID=myce; Password=****;"), true) {}

}
我得到了这个内部错误:

{"ORA-00942: table or view does not exist"}
而且这个表是存在的


我做错了什么?

您的问题很可能是因为EF将查询以引号形式传递给Oracle,这意味着表和字段上的大小写必须与数据库中的大小写匹配

因此,如果你有以下几点:

select name from persons;
EF代码可能会触发以下SQL:

select "NAME" from "PERSONS";
将此添加到OnModelCreating函数:

modelBuilder.Conventions.Remove<ColumnTypeCasingConvention>();
modelBuilder.Conventions.Remove();
…并使用大写属性名而不是正常的句子大小写来构造POCO对象

如果要查看SQL,请中断代码并查看DbContext.Persons对象。您应该看到它将用于查询整个表的实际sql命令(相当大)

注意


我们在生产中首先使用Oracle EF代码。尽管没有官方支持,但最新的ODAC版本中似乎没有任何东西可以阻止您。

正如Nick在回答中所说,问题与生成的查询的引号和大小写有关,但与表名无关,而与模式名有关:

SELECT * 
FROM "myce"."PERSONS" "Extent1"
因此,解决方案非常简单,只需将用户id和架构名称大写:

modelBuilder.Entity<Person>().ToTable("PERSONS","MYCE");

因此,这些名称在数据库和类中都更易于读取。

您可以在针对dbcontext对象运行的linq查询上调用ToString。这将向您显示正在生成的SQL。这会帮助你找到问题所在

我的问题有两方面:

  • 我的桌名是复数的
  • 我的表名以“dbo”开头

  • 如果您不想将应用程序的每一列映射为@fcaldera提到的报价问题的解决方法,您可以使用“Devart's dotConnect for Oracle”提供程序

    只需要以下代码:

    var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
    
    config.Workarounds.DisableQuoting = true;
    
    现在,您可以将一个类“MyObject”映射到一个表MyObject而不会出现问题。列也是一样的


    注意:NuGet版本的“dotConnect for Oracle”不支持实体框架。有必要从Devart的网站下载试用版或专业版。

    嘿,Nick,谢谢你的回答。问题出在架构名称中。它必须是大写的。我同意你的意见。ColumnTypeCasingConvention不存在。我的类和属性都带有数据注释,分别使用大写模式/ColumnName,但它们仍然不起作用。但是,使用DbSet.Find不起作用,DbSet.SingleOrDefault()被认为是表注释属性中的一个输入错误,因此DbSet.Find似乎遍历所有类并将它们映射到它们的表,而使用SingleOrDefault()只在运行时映射该查询所需的表,因为我就是这样注意到输入错误的。我在想,既然SingleOrDefault工作,所有的表名都很好。长话短说,查找映射您的整套DbContext对象列表。
        [Column("FIRST_NAME")]
        public string FirstName { get; set; }
    
    var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
    
    config.Workarounds.DisableQuoting = true;