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

时间:2012-03-15 23:29:45

标签: asp.net-mvc-3 oracle ef-code-first odp.net dbcontext

我正在尝试使用ODP.net在Oracle下使用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) {}

}

问题在于,当我尝试做这样的事情时:

MyCEContext context = new MyCEContext();
Person p = context.Persons.Find(1);

我得到了这个内心错误:

{"ORA-00942: table or view does not exist"}

表格存在。

我做错了什么?

4 个答案:

答案 0 :(得分:6)

正如尼克在他的回答中写道,这个问题与生成的查询的引用和案例有关,但不是与表的名称有关,而是与模式的名称有关:

SELECT * 
FROM "myce"."PERSONS" "Extent1"

所以解决方案非常简单,只是大写用户ID和模式名称:

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

通常,所有内容都必须为大写:表格,架构和字段名称。但最好使用Column属性注释每个映射属性,而不是使用大写属性名称:

    [Column("FIRST_NAME")]
    public string FirstName { get; set; }

因此,在数据库和类中都可以更容易地读取名称。

答案 1 :(得分:3)

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

所以如果你有以下内容:

select name from persons;

EF代码可能会触发以下SQL:

select "NAME" from "PERSONS";

将此添加到OnModelCreating函数:

modelBuilder.Conventions.Remove<ColumnTypeCasingConvention>();

...并使用大写属性名称而不是正常的发送案例来构造您的POCO对象。

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

注意

我们在生产中使用Oracle EF Code First。虽然没有得到官方支持,但最新的ODAC版本似乎没有任何内容可以阻止您。

答案 2 :(得分:1)

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

我的问题有两个:

  1. 我的桌名正在多元化
  2. 我的表名以“dbo”开头。

答案 3 :(得分:0)

如果您不希望将应用程序的每一列映射为@fcaldera提及的引用问题的解决方法,则可以使用&#34; Devart的dotConnect for Oracle&#34;提供商。

只需要以下代码:

var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;

config.Workarounds.DisableQuoting = true;

现在你可以映射一个类&#34; MyObject&#34;到没有问题的表MYOBJECT。对于列而言也是如此。

注意: NuGet版本的&#34; dotConnect for Oracle&#34;不支持实体框架。从Devart的网站下载试用版或专业版是必要的。