我正在尝试使用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"}
表格存在。
我做错了什么?
答案 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。这应该可以帮助您找到问题
我的问题有两个:
答案 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的网站下载试用版或专业版是必要的。