Asp.net mvc 3 如何配置DbContext以使用Oracle ODP.Net和EF CodeFirst?
我正试图在Oracle的ODP.net下使用EF CodeFirst。这是我的DbContext类: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
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。这会帮助你找到问题所在 我的问题有两方面:
如果您不想将应用程序的每一列映射为@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;